2012-05-13 7 views
0

Kathy Sierraの本では、Stringのような新しい演算子を使用してStringを作成すると、新しい文字列( "abc")が使用されたため、 Javaは通常の(非プール)メモリに新しいStringオブジェクトを作成し、sはそのオブジェクトを参照します。さらに、リテラル "abc"がプールに配置されます。新しいメソッドとinternメソッドとの比較を使用した文字列オブジェクトの作成

intern()は、文字列プールに文字列がすでに含まれている場合、プールの文字列が返されます。そうでない場合は、Stringオブジェクトがプールに追加され、このStringオブジェクトへの参照が返されます。

newを使用して作成された文字列「abc」がプール内に文字列を配置した場合、intern()は文字列プールに文字列が含まれている場合はプールから文字列を返します。そうでない場合は文字列オブジェクトがプールに追加されます。

また、実際にいくつのオブジェクトが作成されるかを新しいものを使用してStringを作成するかどうかを知りたいですか?

答えて

6

TL; DRnew 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" 
+0

新しいStringオブジェクトをインターンした後、新しいオブジェクトを使用してヒープで作成されたオブジェクトはどうなりますか? – Anand

+0

@anand:(これらはすべてヒープにあります)新しい文字列オブジェクトを 'internする '場合、他の未処理の参照は存在しないと仮定すると、ガベージコレクションの対象となります。それに対する未解決の言及。 'intern' *は、インターンされた' String'への参照を返します。 –

+0

@anand - この特定のケースでは、実行中のクラス/メソッドのコードオブジェクトには、インターンされたStringへの参照が含まれます。つまり、クラスがロードされている間は、 '' abc ''を表すStringは到達可能なままです。 –

0

文字列プールは文字列参照のプールです。オブジェクトはヒープのみで作成されます。

new String("abc").intern()を使用するか、String s = "abc"のような方法を使用する場合。 "abc"を参照する参照が存在する場合、文字列プールがチェックされます。 「ABC」の場合の参照に

はすでにオブジェクトnew String("abc")によって作成その後、プールに存在し、.intern()new String("abc")を使用して作成さString objectを参照する参照で呼び出されたガベージコレクションの対象です。より明確にするため、以下のコードを参照してください。

public static void main(String[] args) { 
    String s = new String("abc"); 
    String a = s; 
    System.out.println(s==a);// true 
    String b = "abc"; 
    s = s.intern(); 
    System.out.println(s==a);// false 
} 
関連する問題