4

我有这个代码

String a="test";
String b="test";
if(a==b)
   System.out.println("a == b");
else
   System.out.println("Not True");

并且每个 Java 专家都知道,由于String pooling 设施if(a==b),这里将通过。 根据字符串池这就是为什么在上面的代码中条件已经通过。现在问题来了。在上面的代码中,当我添加了另外两行时,现在 String a & b 的值将是。新代码将是这样的

Each time your code creates a string literal, the JVM checks the string literal pool first. If the string already exists in the pool, a reference to the pooled instance is returned. If the string does not exist in the pool, a new String object is created and placed in the pool. JVM keeps at most one object of any String in this pool. String literals always refer to an object in the string pool

a+="1"b+="1"Test1

String a="test";
    String b="test";
    if(a==b)
        System.out.println("a == b");
    else
        System.out.println("Not True");
        a+="1"; //it would be test1 now
        b+="1"; //it would also be test1 now
    if(a==b)
       System.out.println("a == b");
    else
      System.out.println("Not True");

现在在更改字符串之后,当我放置if(a==b)检查时它没有通过。我知道这是由于字符串的不变性特性但我想知道

1)更改后,JVM 是否将它们与两个不同的对象一起存储?
2) JVM 是否要求new String()更改任何字符串?
3)为什么即使我在更改时尝试调用它们也没有将它们作为单个引用intern()
Q3 提示:
a+="1".intern();
b+="1".intern();

4

3 回答 3

1

1)是的,这就是a == b失败的原因。这些新字符串不是字符串池的一部分,因为它们不是一开始的文字。

2)正如@LuiggiMendoza所指出的,如果编译器有办法知道字符串的值,它将使用String构造函数,否则它将在StringBuilder内部使用a(最终它将使用String构造函数返回最终的字符串)

3)即使“1”是字面量,其结果a + "1".intern();本身也不是字面量,而是用String构造函数新建的String对象,所以不会加入String池中。

于 2013-07-26T05:33:27.763 回答
1

因为字符串是不可变的。更改字符串后,您的变量现在将引用不同的String.

创建 时,如果值在编译时未知,则new StringJVM 使用;StringBuilder否则,使用标准String构造函数。

添加"1".intern()时,.intern()适用于"1"不是 a + "1");串联产生新String对象(NOT文字),因此a不要b引用相同的对象。请记住,当Strings通过new运算符创建时,您会强制分配新内存。

为了ab实际引用同一个对象,您必须同时调用.intern()它们:

_a = _a.intern(); //adds _a to the String pool
_b = _b.intern(); //makes _b point to the same object as _a, since _b.equals(_a)
于 2013-07-26T05:33:50.027 回答
1

发生这种情况是因为当您执行 '+=' 时,由于字符串的不变性,它会在堆上创建一个不在字符串池中的新对象。如果你想要它在字符串池中,那么再次在两个字符串上调用intern()方法。

String a="test";
    String b="test";
    if(a==b)
        System.out.println("a == b");
    else
        System.out.println("Not True");
        a+="1"; //it would be test1 now
        b+="1"; //it would also be test1 now

       a=a.intern();
       b=b.intern();

    if(a==b)
       System.out.println("a == b");
    else
      System.out.println("Not True");

现在它在这两种情况下都会产生'a == b'。有关字符串池的更多信息,请访问此链接

于 2013-07-26T05:41:15.360 回答