7

次のプログラムを実行しました。

    String firstString = "String";
    String secondString = "String";
    String thirdString = new String("String");
    System.out.println(firstString == secondString);
    System.out.println(firstString == thirdString);
    System.out.println(firstString.intern() == thirdString);
    System.out.println(firstString.intern() == thirdString.intern());
    System.out.println(firstString.intern().equals(thirdString.intern()));
    System.out.println(firstString == thirdString);

そして私の出力は

true
false
false
true
true
false

jvm は、同じ内容の文字列を同じ文字列としてプールすることを知りました。そうですか?それが本当なら、firstString == thirdString が false を返さないのはなぜですか? jvm は、new 演算子ではなく :"" で初期化された文字列のみをプールしますか?

4

4 に答える 4

6

プーリングは文字列リテラルのみに関連するためfirstStringsecondString実際には同じオブジェクトです-thirdStringヒープ上に新しいオブジェクトを作成するように明示的に要求した場合と同様です。

spec の文字列リテラルに関するセクションを読むことをお勧めします。

文字列がプールされる方法と時期に関する詳細情報を提供します。

また、セクションの最後にある次の箇条書きにも注意してください。

  • 同じパッケージ (§7) 内の同じクラス (§8) 内のリテラル文字列は、同じ String オブジェクト (§4.3.1) への参照を表します。
  • 同じパッケージ内の異なるクラス内のリテラル文字列は、同じ String オブジェクトへの参照を表します。
  • 同様に、異なるパッケージの異なるクラス内のリテラル文字列は、同じ String オブジェクトへの参照を表します。
  • 定数式 (§15.28) によって計算された文字列は、コンパイル時に計算され、リテラルであるかのように扱われます。
  • 実行時に連結によって計算された文字列は新しく作成されるため、区別されます。
于 2012-09-09T12:55:55.973 に答える
2

firstString と secondString の場合、JVM は文字列プールを検索し、"String" の参照を返します。

thirdString の場合、JVM は文字列プールをルックアップせず、ヒープに String オブジェクトを作成するだけです。

OneString.intern() の場合、JVM は文字列プールで参照を検索し、OneString が存在しない場合は文字列プールに OneString を追加し、参照を返します。

于 2012-09-09T13:04:34.023 に答える
0

thirdStringプールからではありません。newこれは文字列リテラルではありません。演算子を使用して動的に作成しました。

secondString一方、 - はプールから取得されるため (文字列リテラルをそれに割り当てます)、同じオブジェクトが と の両方firstStringに割り当てられますsecondString

于 2012-09-09T12:56:10.940 に答える
0

"firstString == thirdString" は false を返します。

メソッド intern は「文字列オブジェクトの正規表現を返します」。インターンされた文字列を割り当てる場合:

thirdString=thirdString.intern();

最後の "firstString == thirdString" は true を返します

于 2012-09-09T12:56:46.783 に答える