7

次のコードがあるとします。

StringBuffer str2 = new StringBuffer(" I don't");
    StringBuffer str3 = str2.append(" get it.");
    if (str2 == str3)
    {
        System.out.println("Equal");
    }

私の講師によると、この場合、str2との両方str3が同じオブジェクトを参照し、「I don't get it」という文字列が「文字列プール」に挿入されます。

理由がわかったと思いますが、同じオブジェクトを参照str2str3ますが、なぜ「I don't get it.」という文字列を参照しますか。str3割り当てが発生したときに文字列プールに入れますか?

たとえば、私が行う場合:

 String s = "abcd";

次に、文字列「abcd」がまだ存在しない場合、「文字列プール」に挿入されることがわかりました。

説明をいただければ幸いです。

4

6 に答える 6

5

「I don't get it.」という文字列が表示されるのはなぜですか。ストリングプールに入ります。

文字列は"I don't get it."インターニング プールに入りません。

それを確認する 1 つの方法は次のとおりです。

StringBuffer str2 = new StringBuffer(" I don't");
StringBuffer str3 = str2.append(" get it.");
String str = new String(str3.toString());
if (str == str.intern()) {
    System.out.println("It was not interned before"); // <<== This is printed
} else {
    System.out.println("It was interned before");
}

Stringのコンテンツがインターンされている場合、 の呼び出しは別intern()の (「正規の」) オブジェクトを返します。ご覧のとおり、上記は同じオブジェクトを返します。つまり、呼び出したオブジェクトがintern()「正規の」オブジェクトになった (つまり、インターンされた) ことを意味します。

一方、 を削除するappendと、別の結果が得られます。

StringBuffer str2 = new StringBuffer(" I don't");
StringBuffer str3 = str2;
String str = new String(str3.toString());
if (str == str.intern()) {
    System.out.println("It was not interned before"); // <<== This is printed
} else {
    System.out.println("It was interned before");
}

現在、内部の文字列str3" I don't". の作成に使用された文字列定数と同じであるため、そのコピーは既にインターンされていますstr2

最初のプログラムと2 番目のプログラムを並べて実行して、違いを自分で確認できます。

その理由str2 == str3true文字列プールとは何の関係もありません (俗語は"string interning"です)。が呼び出されたオブジェクト、つまりStringBuffer.appendを返すため、この 2 つは等しいです。2 番目のオブジェクトはありません。2 つの参照を持つオブジェクトは 1 つだけです。その内容はと文字列の連結です。appendstr2StringBufferStringBuffer" I don't"" get it."

于 2013-04-03T12:44:10.140 に答える
2

欠けているのは、文字列リテラルの概念です。

次の場合にプールに追加される文字列:

  • リテラルとして定義されます。
  • その上でメソッド intern を呼び出します。

まだプールにありません。

あなたの例では、文字列リテラルを type のオブジェクトに入れますStringBuffer。そのオブジェクトから文字列を取得するには、 を呼び出す必要がありますtoString()。結果を文字列プールに追加するには、その文字列をさらに呼び出す必要がありintern()ます。

簡単なテストを実行できることを証明するため。

String s1 = "This is a simple test";
String s2 = "This is a simple test";

System.out.println(s1 == s2);

StringBuffer sb1 = new StringBuffer(s1);
StringBuffer sb2 = new StringBuffer(s2);

String result1 = sb1.toString();
String result2 = sb2.toString();

System.out.println(result1 == result2);

String internedResult1 = result1.intern();
String internedResult2 = result2.intern();

System.out.println(internedResult1 == internedResult2);

コード出力は次のようになります。

真偽 真
_

于 2013-04-03T13:20:40.637 に答える
0

StringBuffer(interned) ではなく、オブジェクトを比較していますString。実装を見ると、StringBuffer.append( String )それが で終わっていることがわかります。return this;したがって、str2str3は同じオブジェクトです。

public synchronized StringBuffer append(String str) {
super.append(str);
    return this;
}

編集: コード内の 2 つの文字列リテラルが ("文字列プール" で) インターンされている間、結合された文字列 "I don't get it" はインターンされません。これは、コードを調べることで明らかStringBufferです (これは、組み合わせをchar[]内部的に配列として表します)。

乾杯、

于 2013-04-03T12:44:37.977 に答える