4

私はこのコードを持っています

String a="test";
String b="test";
if(a==b)
   System.out.println("a == b");
else
   System.out.println("Not True");

そして、すべての Java 専門家は、文字列プーリング機能if(a==b)により、ここが通過することを知っています。 文字列プーリングによると、それが上記のコードで条件が合格した理由です。ここで質問があります。上記のコードで、2 行追加すると、文字列 a と b の値は になります。新しいコードは次のようになります

Each time your code creates a string literal, the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string does not exist in the pool, a new String object is created and placed in the pool. JVM keeps at most one object of any String in this pool. String literals always refer to an object in the string pool

a+="1"b+="1"Test1

String a="test";
    String b="test";
    if(a==b)
        System.out.println("a == b");
    else
        System.out.println("Not True");
        a+="1"; //it would be test1 now
        b+="1"; //it would also be test1 now
    if(a==b)
       System.out.println("a == b");
    else
      System.out.println("Not True");

文字列を変更した後、if(a==b)チェックを入れたときに合格しませんでした.これは文字列の不変性機能によるものであることはわかっていますが、知りたい

1)変更後、JVMはそれらを2つの異なるオブジェクトで保存しますか?
2) JVM はnew String()文字列の変更を要求しますか?
3)intern()変更中にコールしようとしても、シングルとして参照されないのはなぜですか?
Q3 ヒント:
a+="1".intern();
b+="1".intern();

4

3 に答える 3

1

これは、「+=」を実行すると、文字列の不変性により、文字列プールにないヒープに新しいオブジェクトが作成されるために発生しています。String プールでそれが必要な場合は、両方の String でintern()メソッドを再度呼び出します。

String a="test";
    String b="test";
    if(a==b)
        System.out.println("a == b");
    else
        System.out.println("Not True");
        a+="1"; //it would be test1 now
        b+="1"; //it would also be test1 now

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

    if(a==b)
       System.out.println("a == b");
    else
      System.out.println("Not True");

これで、どちらの場合も 'a == b' が生成されます。文字列プーリングの詳細については、このリンクにアクセスしてください。

于 2013-07-26T05:41:15.360 に答える
1

a == b1) はい、それが失敗する理由です。これらの新しい文字列は、最初からリテラルではなかったため、文字列プールの一部ではありません。

2) @LuiggiMendoza が指摘したように、コンパイラが文字列の値を知る方法を持っている場合は String コンストラクターStringBuilderを使用します。最終的な文字列を返す)

3) "1" がリテラルでa + "1".intern();あっても、それ自体の結果はリテラルではなく、String コンストラクターで作成された新しい String オブジェクトであるため、String プールには追加されません。

于 2013-07-26T05:33:27.763 に答える
1

文字列は不変なので。文字列を変更すると、変数は別の を参照するようになりますString

を作成するときnew String、JVM はStringBuilderコンパイル時に値が不明な場合に使用します。それ以外の場合は、標準のStringコンストラクターが使用されます。

を追加する場合"1".intern()、は( not )に.intern()適用されます。連結によって新しいオブジェクト ( NOTリテラル) が生成されるため、 とは同じオブジェクトを参照しません。演算子を使用して作成すると、新しいメモリが強制的に割り当てられることに注意してください。"1" a + "1"StringabStringsnew

a同じオブジェクトをb実際に参照するには、両方を呼び出す必要があり.intern()ます。

_a = _a.intern(); //adds _a to the String pool
_b = _b.intern(); //makes _b point to the same object as _a, since _b.equals(_a)
于 2013-07-26T05:33:50.027 に答える