akios @ ウィキ

3.10.5. 文字列リテラル

最終更新:

akios

- view
管理者のみ編集可

3. 字句構造

3.1. Unicode

3.2. 字句変換

3.3. Unicodeエスケープ

3.4. 行終端子

3.5. 入力要素とトークン

3.6. 空白

3.7. コメント

3.8. 識別子

3.9. キーワード

3.10. リテラル

3.10.1. 整数リテラル

3.10.2. 浮動小数点リテラル

3.10.3. ブールリテラル

3.10.4. 文字リテラル

3.10.5. 文字列リテラル

文字列リテラル(string literal)は2重引用符で0個以上の文字を括ったものです。文字はエスケープシーケンスでも構いません。U+0000~U+FFFFの範囲にある文字に対しては1つのエスケープシーケンスで、U+010000~U+10FFFFの範囲にある文字に対してはUTF-16サロゲートコード単位を表す2つのエスケープシーケンスで表せます。

StringLiteral:
  " StringCharactersopt "

StringCharacters:
  StringCharacter
  StringCharacters StringCharacter

StringCharacter:
  InputCharacter but not " or \
  EscapeSequence

エスケープシーケンスの定義については3.10.6.を参照してください。

文字列リテラルは常にString型です。

始まりの"の後、終わりの対になる"の間に行終端子が入るとコンパイルエラーとなります。

3.4.で明記した通り、文字CRとLFは決してInputCharacterとはなりません。それらは LineTerminator を構成するものとして認識されます。

長い文字列リテラルを短い部分文字列に分解して文字列連結演算子+を使用した(おそらく括弧で括られた)式として書くことができます。

以下は文字列リテラルの例です。:

""          // 空文字列
"\""         // "のみの文字列
"This is a string"  // 16文字の文字列
"This is a " +    // 実際には文字列値の定数式、
  "two-line string" // 2つの文字列リテラルから構成されています

Unicodeエスケープはごく初期に処理されるため、ラインフィード(LF)の値をとる文字リテラルとしての"\u000a"という書き方は正しくありません。Unicodeエスケープ"\u000a"変換ステップ1において実際のラインフィードに変換され、ステップ2においてラインフィードはLineTerminatorとなるため、ステップ3においてその文字リテラルは有効ではりません。代わりに、エスケープシーケンス"\n"を使用します。同様にキャリッジリターン(CR)の値をとる文字リテラルとしての"\u000d"という書き方は正しくありません。代わりに"\r"を使用してください。最後に、2重引用符(")を含む文字列リテラルで"\u0022"と書くことはできません。

文字列リテラルはStringクラスのインスタンスへの参照です(4.3.1.4.3.3.)。

さらに、文字列リテラルは常にStringクラスの同じインスタンスを参照しています。文字列リテラル、より一般的に定数式の値である文字列、はメソッドString.internを使って一意のインスタンスを共有するために"抑留(intern)”されます。

例3.10.5-1. 文字列リテラル


package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((hello == ("Hel"+lo)) + " ");
        System.out.println(hello == ("Hel"+lo).intern());
    }
}
class Other { static String hello = "Hello"; }

と以下のコンパイル単位:

package other;
public class Other { public static String hello = "Hello"; }

で構成されるプログラムから以下の出力が得られます。:

true true true true false true

この例で以下の6点を解説します。
  • 同一パッケージ内の同一クラス内の文字列リテラルは同一のStringオブジェクトへの参照として表されます。
  • 同一パッケージ内の異なるクラス内の文字列リテラルは同一のStringオブジェクトへの参照として表されます。
  • 異なるパッケージ内の異なるクラス内の文字列リテラルも同様に同一のStringオブジェクトへの参照として表されます。
  • 定数式によって計算される文字列はコンパイル時に計算されリテラルと同じように扱われます。
  • 実行時に連結により計算される文字列は新規に作成されるので異なるものとなります。
  • 計算される文字列を明示的に抑留すると、同一の内容である既存の文字列と同じ文字列となります。

3.10.6. 文字・文字列リテラル用のエスケープシーケンス

3.10.7. ヌルリテラル

3.11. 分離子

3.12. 演算子

目安箱バナー