4

重複の可能性:
文字列のインターン メソッドを使用する必要があるのはいつですか?
ストリングインターンとは?

次のコードの内部の仕組みを説明してください。

System.out.println(new String("ABC").intern()==new String("ABC").intern());

上記のコードでは、「true」と出力されます。ただし、Java の規則に従って、new 演算子の場合、常に新しいオブジェクトが作成されます。 object.intern()メソッドは、文字列プールにオブジェクトも作成します。私の質問は、上記のコードで作成されるオブジェクトの数です。

私によると、3 つの新しいオブジェクトが作成されます。1 つは String プールに行き、2 つの匿名オブジェクトは new オペレーターによって作成されます。しかし、よくわかりません。

私が間違っている場合は、説明してください。

4

3 に答える 3

1

オプティマイザーに賢さがないと仮定すると、2 つのオブジェクトが作成されます。(十分に賢いオプティマイザは、これを無条件trueに最適化できます。その場合、オブジェクトは作成されません。)

tl;dr version: String プールに入る文字列がこのステートメントの一部として生成されないことを除いて、3 の答えでほとんど正解でした。すでに作成されています。

"ABC"まず、リテラルを邪魔にならないようにしましょう。ランタイムではStringオブジェクトとして表されますが、それは pergen に存在し、JVM の存続期間中に一度だけ作成されます。これがその文字列リテラルを使用する最初のクラスである場合、それはクラスのロード時に作成されました ( JLS 12.5を参照してください。以前に存在していた場合を除き、クラスがロードされたときに String が作成されたと記載されています)。

そのため、最初にnew String("ABC")を作成します。これは参照を chars 配列Stringに単純にコピーし"ABC"(ただし、新しいオブジェクトは作成しません)、リテラルを表す String からハッシュします(これも、この行の一部として作成されません)。この.intern()メソッドは、等しい文字列がすでに permgen にあるかどうかを調べます。それは (最初にリテラルを表す文字列に過ぎない) なので、それがその関数が返すものです。だから、new String("ABC").intern() == "ABC"JLS 3.10.5を参照してください。特に:

さらに、文字列リテラルは常に String クラスの同じインスタンスを参照します。これは、文字列リテラル (より一般的には、定数式の値である文字列 (§15.28)) が、メソッド String.intern を使用して一意のインスタンスを共有するために「インターン」されているためです。

の 2 回目の発生でもまったく同じことが起こりnew String("ABC").intern()ます。また、どちらのメソッドもリテラルintern()と同じオブジェクトを返すため、同じ値を表します。"ABC"

少し分解します:

String a = new String("ABC"); // a != "ABC"
String aInterned = a.intern(); // aInterned == "ABC"

String b = new String("ABC"); // b != "ABC"
String bInterned = b.intern(); // bInterned == "ABC"

System.out.println(new String("ABC").intern()==new String("ABC").intern());
                                            // ... is equivalent to... 
System.out.println(aInterned == bInterned); // ...which is equivalent to...
System.out.println("ABC" == "ABC");         // ...which is always true.
于 2013-01-18T07:11:38.333 に答える
0

メソッドを呼び出すとintern()、jvm は、指定された文字列が文字列プールにあるかどうかを確認します。そこにある場合は、それへの参照を返します。そうでない場合は、プールに新しい文字列を作成し、それへの参照を返します。あなたの場合:System.out.println(new String("ABC").intern()==new String("ABC").intern());

最初new String("ABC").intern()はプールに文字列「ABC」を作成しますnew String("ABC").intern()。2回目に呼び出すと、jvmは以前に作成された文字列への参照を返します。これが、true両方を比較するときに得られる理由です(btnは同じ参照を指しています)。

于 2013-01-18T06:02:32.370 に答える
0

new操作は新しいオブジェクトを作成するため、2つの匿名オブジェクトがありintern()、まだ作成されていない場合にのみ文字列プールに新しい文字列を作成し、参照を返すので 、あなたは正しいと思います

于 2013-01-18T06:29:27.347 に答える