2

String クラスの intern メソッドのjavaDocsから:

intern メソッドが呼び出されたときに、equals(Object) メソッドによって決定されたこの String オブジェクトと等しい文字列がプールにすでに含まれている場合、プールからの文字列が返されます。それ以外の場合は、この String オブジェクトがプールに追加され、この String オブジェクトへの参照が返されます。

次の使用例を検討してください。

    String first = "Hello";
    String second = "Hello";

    System.out.println(first == second);

    String third = new String("Hello");
    String fourth = new String("Hello");

    System.out.println(third == fourth);

    System.out.println(third == fourth.intern());
    System.out.println(third.intern() == fourth);
    System.out.println(third == fourth);

    System.out.println(third.intern() == fourth.intern());
    System.out.println(third.intern() == first);

    String fifth = new String(new char[]{'H','e','l', 'l', 'o'});
    String sixth = new String(new char[]{'H','e','l', 'l', 'o'});

    System.out.println(fifth == fifth.intern());
    System.out.println(sixth == sixth.intern());

    String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
    String eight = new String(new char[]{'H','e','l', 'l', 'o' , '2'});

    System.out.println(seven == seven.intern());
    System.out.println(eight == eight.intern());

以下が偽であるのに対し、なぜseven == seven.intern()であるかを誰かが説明できますか:

  • System.out.println(fifth == fifth.intern());
  • System.out.println(sixth == sixth.intern());
  • System.out.println(eight == eight.intern());
4

4 に答える 4

2

7 は、文字列 'hello2' を初めて使用するときです。そのためintern、文字列をプールに挿入します(また、それを返します)。それはあなたの7に等しいからです。

8 で作業する場合、文字列は既にプール内にあります (seven.intern()前に実行eight == eight.intern()することにより、式の左側に新しく作成されたeight文字列が得られ、右側にプールから 7 によって作成された文字列が得られます)。 、同じではありません

于 2016-03-11T05:47:11.443 に答える
1

構文を使用する場合new String()、String プールを利用するのではなく、プール内にあるかどうかに関係なく、String の新しいインスタンスを作成するためです。

物語の教訓..決して使用しないでくださいnew String()

JVM は、「内部化された」文字列が既に存在するかどうか、または内部化する必要があるかどうかを決定する選択肢を持っています。すなわち:

文字列リテラルを導出するために、Java 仮想マシンは、CONSTANT_String_info 構造体によって指定されたコード ポイントのシーケンスを調べます。

メソッド String.intern が、CONSTANT_String_info 構造体によって指定されたものと同一の Unicode コード ポイントのシーケンスを含むクラス String のインスタンスに対して以前に呼び出された場合、文字列リテラルの派生の結果は、クラス String の同じインスタンスへの参照になります。それ以外の場合は、CONSTANT_String_info 構造体によって指定された一連の Unicode コード ポイントを含むクラス String の新しいインスタンスが作成されます。そのクラス インスタンスへの参照は、文字列リテラルの派生の結果です。最後に、新しい String インスタンスのインターン メソッドが呼び出されます。

于 2016-03-11T05:42:10.207 に答える
0
  String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});

リテラル " Hello2" により、文字列定数プール内にオブジェクトが作成されます。新しい String は、リテラルのオブジェクトのコンテンツのコピーを使用して、ヒープ上に新しい String オブジェクトを作成します。

そのような String オブジェクトは作成しないでください。不要で非効率的だからです。実行System.out.println(seven == seven.intern());すると、 が出力されますtrue

これSystem.out.println(eight == eight.intern());で、文字列は既に存在するため、文字列プールから返されるため、出力されますfalse

于 2016-03-11T06:02:15.787 に答える
0

pczeusは正しいです。より詳しい情報:

5 番目は、値「Hello」を含む新しい文字列 (プールはチェックされませんでした) です。intern() すると、戻り値は 4 番目 (インターンされた "Hello" の最初の出現) であり、5 番目とは異なります。

6番目も同じ答え。

Seven は "Hello2" の最初の出現であり、'seven == Seven.intern()' を呼び出すまでインターンされません。その時点でインターンされるため、intern() の戻り値は 7 です。

8 は、「Hello2」の別の新しいインスタンスです。インターンされると、戻り値は 8 ではなく 7 になります。

于 2016-03-11T05:47:53.180 に答える