0

キャシー シエラの本で、String s = new String("abc") のような new 演算子を使用して String を作成すると、この場合、new キーワードを使用したため、Java は通常の (非プール) メモリに新しい String オブジェクトを作成することを読みました。 s はそれを参照します。さらに、リテラル "abc" がプールに配置されます。

intern() は、String プールに既に文字列が含まれている場合、プールからの文字列が返されることを示しています。それ以外の場合は、String オブジェクトがプールに追加され、この String オブジェクトへの参照が返されます。

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

また、new を使用して String を作成した場合、実際に作成されるオブジェクトの数を知りたいですか?

4

2 に答える 2

6

TL;DR : 本当にやらなければならないことがあれば、やらなければならないnew String("abc")ことがわかり、その理由もわかるでしょう。非常にまれなので、必要がないと言っても過言ではありませんを使用するだけ"abc"です。


長いバージョン:

コードがある場合new String("abc")、次のことがさまざまな時点で発生します。

  • そのコードを含むクラスが読み込まれるときに、文字を含む文字列"abc"がまだインターン プールにない場合は、作成されてそこに配置されます。
  • new String("abc")コードが実行されると :
    • インターン プールからの文字列への参照がコンストラクタ"abc"に渡されます。String
    • 渡された からコンストラクターに文字をコピーすることにより、新しい Stringオブジェクトが作成され、初期化されます。String
    • 新しいStringオブジェクトが返されます。

new を使用して作成された文字列 "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

また、new を使用して String を作成した場合、実際に作成されるオブジェクトの数を知りたいですか?

少なくとも 1 つのStringオブジェクト (インターンされていない新しいオブジェクト) を作成し、場合によっては 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"
于 2012-05-13T10:57:44.837 に答える