7

重複の可能性:
Java Strings および StringPool

2 つの文字列を作成しました

String s1="MyString";
String s2=new String("MyString");
System.out.println(s1==s2);

それは印刷し"false"ます。String プールは、同じ String リテラルに対して 2 つのオブジェクトを作成しないことがわかっています。

では、ここで何が起こっているのでしょうか? 同じ文字列リテラル「MyString」の文字列プールに 2 つの異なる文字列オブジェクト (リテラル) を作成しています。

私は equals()メソッドがtrueここに戻ることを知っています。

ただし、使用する==場合は、2 つの参照を比較し、文字列定数プール内の同じ文字列オブジェクトを参照する必要があります。

一致が見つかった場合でも、String プール内の既存の String オブジェクトを参照していないのはなぜですか?

4

5 に答える 5

14

1つ目はプールに移動し、2つ目はヒープに格納されます。

s2 = s2.intern();を返すために使用しtrueます。

文字列に対してを実行するintern()と、JVMは文字列がプールに存在することを確認します。まだ存在しない場合は、プールに作成されます。それ以外の場合は、既存のインスタンスが返されます。==これが行動の説明だと思います。

String s1="MyString";
String s2=new String("MyString");
s2 = s2.intern();
System.out.println(s1==s2);

参考までに、String.intern()ドキュメントの内容は次のとおりです。

/**
 * Returns a canonical representation for the string object.
 * <p>
 * A pool of strings, initially empty, is maintained privately by the
 * class <code>String</code>.
 * <p>
 * When the intern method is invoked, if the pool already contains a
 * string equal to this <code>String</code> object as determined by
 * the {@link #equals(Object)} method, then the string from the pool is
 * returned. Otherwise, this <code>String</code> object is added to the
 * pool and a reference to this <code>String</code> object is returned.
 * <p>
 * It follows that for any two strings <code>s</code> and <code>t</code>,
 * <code>s.intern()&nbsp;==&nbsp;t.intern()</code> is <code>true</code>
 * if and only if <code>s.equals(t)</code> is <code>true</code>.
 * <p>
 * All literal strings and string-valued constant expressions are
 * interned. String literals are defined in section 3.10.5 of the
 * <cite>The Java&trade; Language Specification</cite>.
 *
 * @return  a string that has the same contents as this string, but is
 *          guaranteed to be from a pool of unique strings.
 */
public native String intern();
于 2012-08-20T12:04:43.223 に答える
6

この行では、の新しいインスタンスをString s2=new String("MyString");作成しているので、それは確かにと同じインスタンスにはなりません。Strings1

もし、するなら:

System.out.println(s1=="MyString");

あなたは得るでしょうtrue

于 2012-08-20T12:04:21.413 に答える
3

s2は文字列リテラルではなく、使用時に1つから構築されましたnewが、リテラルではなく、新しいオブジェクトです。

于 2012-08-20T12:04:30.533 に答える
3

Literal Pool実際には、1つが入っている 2 つの異なるオブジェクトを作成しています。Heap

String s1 = "MyString"; //literal pool
String s2 = new String("MyString"); //in heap
s.o.p(s1==s2); // false, because two different instances
s.o.p(s1.equals(s2)); // true, compares the contents of the string.

equals代わりに を使用する必要があります==。を呼び出すことにより、文字列オブジェクトをヒープから文字列リテラル プール (または定数プール) にプッシュできますString.intern()

于 2012-08-20T12:06:44.970 に答える
0

String文字列プールは2つのインスタンスを作成していません。2番目のインスタンスを作成するのは、コンストラクター呼び出しです。String(String original)のjavadocから:

新しく作成されたStringオブジェクトを初期化して、引数と同じ文字シーケンスを表すようにします。つまり、新しく作成された文字列は引数文字列のコピーです。オリジナルの明示的なコピーが必要でない限り、文字列は不変であるため、このコンストラクターを使用する必要はありません。

したがって、2番目のインスタンスを作成しているので、==正しく戻りますfalse(そして、equals(Object anObject)は戻りtrueます)。

于 2012-08-20T12:12:15.903 に答える