1

私は次のテストを行っています:

public class EqualityTest
{
    String one = new String("Hello world");
    String two = new String("Hello ") + new String("world");

    @Test
    public void testStringPool()
    {
        assertFalse(one == two); // FALSE!!!
        assertTrue(one.equals(two));
        assertTrue(one.intern().equals(two.intern()));
    }
}

Javaの文字列プールの性質により、VMはプール内の同じ文字列を指す1つと2つを割り当てると予想していました。この場合、なぜ私の理解が間違っているのですか?

4

3 に答える 3

10

Javaの文字列プールの性質により、VMはプール内の同じ文字列を指す1つと2つを割り当てると予想していました。

文字列定数のみが自動的にインターンされます。したがって、コードが次のようになっている場合:

String one = "Hello world";
String two = "Hello " + "world";

...そしてonetwo同じ値を持っていたでしょう。を使用したためnew String(...)、これらの式は定数式ではないため、インターンされません。(もちろん、リテラルはまだインターンされていますが、リテラルから作成された文字列はありません。)

定数式としてカウントされるものの詳細については、JLSのセクション15.28を参照してください。

于 2012-10-22T16:11:06.950 に答える
4

new演算子を使用するたびに、新しいオブジェクトが常にヒープ上に作成されます。したがって、文字列"Hello World"がリテラルプールで使用可能であっても、参照されません。したがって、実際には、ヒープ上に4つのオブジェクトを作成しています:-

  • Hello World---->new String("Hello World");
  • Hello---->new String("Hello");
  • World---->new String("World");
  • そして再び、Hello World---->new String("Hello") + new String("World");

それらとは別に、リテラルプールには「HelloWorld 」、「Hello」、「World」の3つのリテラルが作成されます。

つまり、合計7つのオブジェクトです。


一方、次を使用して文字列を作成しましたか?-

String str = "Hello World";
String str2 = "Hello " + "World";

ここでも、リテラルプールに「HelloWorld 」、「Hello」、「World」の3つのリテラルが作成されますが、最後の2つのリテラルの連結は最初のリテラルを参照します。

したがって、two String参照点は同じliteralsであり、したがって、それらは現在等しくなります。

于 2012-10-22T16:10:06.850 に答える
0

Stringオブジェクトの作成に新しいString( "xyz")が使用されるたびに、新しいオブジェクト参照が作成されます。

例:リテラルのみを処理する場合は、文字列プールの性質が使用されます。

String one = "Hello world";
String two = "Hello "+ "world";

System.out.println(one==two);

trueを出力します。

于 2012-10-22T16:16:03.433 に答える