web-dev-qa-db-ja.com

String.intern()の戻りを説明しました

検討してください:

_String s1 = new StringBuilder("Cattie").append(" & Doggie").toString();
System.out.println(s1.intern() == s1); // true why?
System.out.println(s1 == "Cattie & Doggie"); // true another why?

String s2 = new StringBuilder("ja").append("va").toString();
System.out.println(s2.intern() == s2); // false

String s3 = new String("Cattie & Doggie");
System.out.println(s3.intern() == s3); // false
System.out.println(s3 == "Cattie & Doggie"); // false
_

String.intern()戻り値によって結果が異なる理由を混乱させました:

Internメソッドが呼び出されたときに、equals(Object)メソッドによって決定されたこのStringオブジェクトに等しい文字列がプールにすでに含まれている場合、プールからの文字列が返されます。それ以外の場合、このStringオブジェクトはプールに追加され、このStringオブジェクトへの参照が返されます。

特にこれらの2つのテストの後:

_assertFalse("new String() should create a new instance", new String("jav") == "jav");
assertFalse("new StringBuilder() should create a new instance",
    new StringBuilder("jav").toString() == "jav");
_

私はかつて、何よりも先にインターンされた_special strings_について話している投稿を読んだことがありましたが、今は本当にぼやけています。

_pre-interned_の文字列がある場合、それらのリストのようなものを取得する方法はありますか?私は彼らが何ができるのか知りたいだけです。


更新しました

@Eranと@Slawの協力のおかげで、出力で何が起こったのかを最終的に説明できます

_true
true
false
false
false
_
  1. _"Cattie & Doggie"_はプールに存在しないため、s1.intern()は現在のオブジェクト参照をプールに入れてそれ自体を返すため、s1.intern() == s1;
  2. _"Cattie & Doggie"_は既にプールにあるため、文字列リテラル_"Cattie & Doggie"_は、実際には_s1_であるプール内の参照を使用するだけなので、再度true;を使用します。
  3. new StringBuilder().toString()は、_"Java"_がすでにプールにあるときに新しいインスタンスを作成し、s2.intern()を呼び出すとプール内の参照が返されるため、s2.intern() != s2false;
  4. new String()も新しいインスタンスを返しますが、s3.intern()を実行しようとすると、実際に_s1_であるため、プールに以前に格納された参照が返されますs3.intern() != s3false;
  5. #2で既に説明したように、文字列リテラル_"Cattie & Doggie"_は、プールに既に格納されている参照(実際には_s1_)を返すため、_s3 != "Cattie & Doggie"_とすると、再びfalseになります。

すべてのinterned文字列を取得するためのトリックを提供してくれた@Sunnyに感謝します。

20
Hearen

文字列リテラル(「文字列」のようにハードコードされているもの)は、コンパイラーによってすでにインターンされています。ただし、プログラムで取得される文字列はそうではなく、.intern()メソッドを使用する場合にのみインターンされます。

通常、文字列を手動でインターンすることはありませんが、繰り返し文字列を大量にメモリに格納することがわかっている場合を除き、この方法で多くのメモリを節約できます。

これはここで説明されています: Java String interning? とは

0
maslan