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 将分配一个和两个指向池中相同的字符串。为什么在这种情况下我的理解是错误的?

4

3 回答 3

10

我本来预计,由于 Java 的字符串池性质,VM 将分配一个和两个指向池中相同的字符串。

只有字符串常量会被自动实习。因此,如果您的代码是:

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

......然后onetwo将具有相同的价值。因为您使用过new String(...),所以这些表达式不是常量表达式,因此它们不是实习生。(当然,文字仍然是实习生......但不是从文字创建的字符串

有关什么是常量表达式的详细信息,请参阅JLS 的第 15.28 节。

于 2012-10-22T16:11:06.950 回答
4

每当您使用new 运算符时,总是会在Heap上创建一个新对象。因此,即使字符串“Hello World”Literal Pool中可用,也不会被引用。所以实际上你在堆上创建了4 个对象: -

  • Hello World---->new String("Hello World");
  • Hello---->new String("Hello");
  • World---->new String("World");
  • 再一次,Hello World---->new String("Hello") + new String("World");

除此之外, Literal Pool上还会创建3 个文字- “Hello World”、“Hello”和“World”

所以,总共有7 个对象


另一方面,您是否使用以下方法创建了字符串:-

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

同样,这里将在Literal Pool上创建3 个文字- “Hello World”、“Hello” 和 “World”,但最后两个文字的连接将引用第一个文字

因此two String参考点相同literals,因此它们现在是相等的。

于 2012-10-22T16:10:06.850 回答
0

每当使用 new String ("xyz") 创建 String 对象时,都会创建一个新的对象引用。

例如:当您只处理文字时,将使用字符串池性质。

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

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

将打印真实。

于 2012-10-22T16:16:03.433 回答