TL; DR:new String("abc")
を本当に行う必要がある場合は、その必要があるとわかるので、その理由を知ることができます。珍しいことですが、ほとんどと言えます。ちょうどを使用してください。
ロングバージョン:
あなたはnew String("abc")
次のものが様々な時間に発生したコードがある場合:、
- は、そのコードを含むクラスがロードされている場合、文字の文字列はまだインターンプールに入っていません。作成されてそこに置かれます。
- は
new String("abc")
コードが実行されると:
- インターンプールから文字列への参照は
String
コンストラクタに渡されます。
- 新しい
String
オブジェクトは、コンストラクタに渡されたString
の文字をコピーすることによって作成され、初期化されます。
- 新しい
String
オブジェクトが返されます。
文字列のプールは、そうでない場合は、文字列オブジェクトの文字列が含まれている場合は、新しい使用して作成された文字列「ABC」はまた、プール内の文字列を置き、なぜintern()
は、プールからの文字列が返されることを述べていない場合プールに追加されます。
これは、intern
の機能です。文字列リテラルでintern
を呼び出すことは、何もしないことに注意してください。文字列リテラルはすべて自動的に保持されます。例えば:
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = s1.intern(); // No-op
System.out.println(s1 == s2); // "true"
System.out.println(s1 == "abc"); // "true", all literals are interned automatically
また、私たちは新しいその後、オブジェクトが作成されます実際にどのように多く使用して文字列を作成するかどうかを知りたいですか?しかし、ときに、クラスファイルの再、そのビットは、先に起こる、あなたは少なくとも1つのString
オブジェクト(新しい、非インターン1)を作成し、そしておそらく2(リテラルプールにすでになかった場合
リテラルが読み込まれます)。
String s1 = "abc"; // Get a reference to the string defined by the literal
String s2 = new String(s1); // Create a new `String` object (guaranteed)
System.out.println(s1 == s2); // "false"
String s3 = s2.intern(); // Get the interned version of the string with these characters
System.out.println(s1 == s3); // "true"
新しいStringオブジェクトをインターンした後、新しいオブジェクトを使用してヒープで作成されたオブジェクトはどうなりますか? – Anand
@anand:(これらはすべてヒープにあります)新しい文字列オブジェクトを 'internする '場合、他の未処理の参照は存在しないと仮定すると、ガベージコレクションの対象となります。それに対する未解決の言及。 'intern' *は、インターンされた' String'への参照を返します。 –
@anand - この特定のケースでは、実行中のクラス/メソッドのコードオブジェクトには、インターンされたStringへの参照が含まれます。つまり、クラスがロードされている間は、 '' abc ''を表すStringは到達可能なままです。 –