ここにはそれを説明する非常に多くの回答がありますが、別の回答をさせてください。
文字列は、クラスがロードされ、文字列がリテラルまたはコンパイル時の定数であった場合にのみ、文字列リテラル プールにインターンされます。それ以外の場合は、文字列を呼び出す場合のみ.intern()
。次に、この文字列のコピーがプールにリストされ、返されます。他のすべての文字列の作成はインターンされません。文字列連結 ( +
) は、コンパイル時の定数式でない限り、新しいインスタンスを生成しています*。
まず第一に、決して使用しないでください。それを理解していない場合は、使用しないでください。を使用し.equals()
ます。比較のために文字列をインターンすることは、思ったよりも遅く、ハッシュテーブルを不必要に埋める可能性があります。特に、内容が大きく異なる文字列の場合。
- s3 は定数プールの文字列リテラルであるため、インターンされます。s4 は、インターンされた定数を生成しない式です。
- s4 をインターンすると、s3 と同じコンテンツを持つため、同じインスタンスになります。
- s4 と同じ、式は定数ではありません
- s1+s2 をインターンすると、s3 のインスタンスが取得されますが、s4 はまだ s3 ではありません。
- s4 をインターンする場合、s3 と同じインスタンスです
いくつかの質問:
System.out.println(s3 == s3.intern()); // is true
System.out.println(s4 == s4.intern()); // is false
System.out.println(s1 == "abc"); // is true
System.out.println(s1 == new String("abc")); // is false
* コンパイル時の定数は、連結の両側にリテラルを含む式 ( など"a" + "bc"
) にすることができますが、定数またはリテラルから初期化された最終的な文字列変数にすることもできます。
final String a = "a";
final String b = "b";
final String ab = a + b;
final String ab2 = "a" + b;
final String ab3 = "a" + new String("b");
System.out.println("ab == ab2 should be true: " + (ab == ab2));
System.out.println("a+b == ab should be true: " + (a+b == ab));
System.out.println("ab == ab3 should be false: " + (ab == ab3));