0

やっている:

String a = new String();
String b = a;

そしてやっている:

String a = new String();
String b = a.intern();

同じです ?

実際、テストすると、リファレンスはすべて同じです。

String a = new String("te");
String b = a.intern();
String c = a;
String d = "t" + "e";
System.out.print(a.equals(b));
System.out.print(b.equals(c));
System.out.print(a.equals(d));

文字列が文字列プールにある原因は何ですか?

4

4 に答える 4

5

あなたのequalsテストは参照をチェックしていません- 彼らはstring equalityをチェックしています。ID==の参照を確認するために使用する必要があります。事実上、あなたは一般的な新人 Java の間違いを逆に犯しています。通常、人々は を使用すべきときに を使用します。この特定のケースでは、関連する 2 つの String オブジェクト (定数プールからの文字列と、最初の行で作成された新しい文字列) があるため、これらすべてが出力されます。これらをそれぞれ #1 と #2 と呼ぶと、次のようになります。==equalsfalse

a = #2 // Explicit call to string constructor
b = #1 // intern will return reference to constant pool instance
c = #2 // Direct assignment
d = #1 // Equivalent string constant, so reference to constant pool instance

ただし、これは興味深いかもしれません。

String a = "te";
String b = a.intern();
String c = "t" + "e";
System.out.println(a == b); // true
System.out.println(a == c); // true

"te""t" + "e"は等しい定数文字列式であるため、最終的には単一の文字列への参照になりintern、リテラル プールに既にある文字列を呼び出しても効果はありません。

于 2011-12-17T23:15:20.047 に答える
1

はじめに:"t" + "e"コンパイラによって最適化されるため、文字列リテラルです。この文字列リテラルは、次の行でも使用されています。

String a = new String("te");

ここで、String(String)コンストラクターは文字列の物理コピーを作成します。したがって、これは aとが同じオブジェクトでdないことを意味します。

その後: 2 つの文字列をString.equals(String) 比較します。オブジェクトではなくコンテンツが等しいかどうかを示します。これは、同じ文字シーケンスを持つ 2 つの異なる String オブジェクトが存在する可能性があることを意味しString.equals(String)ますtrue

String.intern()String がまだ String プールにない場合は、String を String プールに入れます。ただし、このメソッドはオブジェクト自体を変更できません。したがって、このコード例は false を出力します。

String literal = "lit";
String nonLiteral = "abclit".substring(3); // equals "lit"
nonLiteral.intern(); // "lit" was already in the String pool
                     // but `nonLiteral` is still `nonLiteral`
System.out.println(literal == nonLiteral); // false

ただし、これを行うと、true が返されます。

String literal = "lit";
String nonLiteral = "abclit".substring(3); // equals "lit"
nonLiteral = nonLiteral.intern(); // "lit" was already in the String pool and
                                  // it will return the object `literal`.
                                  // Now the value is replaced.
System.out.println(literal == nonLiteral); // true
于 2011-12-17T23:27:19.750 に答える
0

equals を使用しても、参照の等価性はテストされません。String の内容が等しいかどうかをテストします。==参照の等価性をテストするために使用する必要があります。

あなたの質問に答えるには、いいえ、同じではありません。最初のスニペットは、2 つの参照 (a と b) を同じ文字列に割り当てます。2 つ目は文字列を作成し、それを a に割り当て、次に文字列をインターンし、インターン プールが返す文字列を b に割り当てます。したがって、a と b は 2 つの異なる String インスタンスを参照できます (空の String が確実にプールにあるため、確かにそうなります。したがって、intern() は a が参照する STring を返しませんが、プールされた空の String を返します)。

于 2011-12-17T23:15:44.093 に答える
0

Stringその文字列値が別のインスタンスから既にインターンされている場合intern()は、以前のインスタンスを返します。

于 2011-12-17T23:16:01.317 に答える