`+ =`运算符总是创建一个新的字符串对象吗?

时间:2017-11-14 17:32:48

标签: java string memory

如果池内存已经有一个具有相似内容的对象,那么如果我们尝试使用不同的引用变量创建相同的对象,那么只创建一个新的引用变量,NO NEW OBJECT IS CREATED.eg;

String s7="1";
String s8 ="1";
System.out.print(s7==s8);  //True

这里只创建了一个对象。 但是在下面的例子中

public class JavaApplication1 {
    public static void main(String[] args) {
        String s1 = "1", s2 = "2", s4 = s1 + s2, s5 = "12";
        final String s3 = s1 + s2;
        s1 += s2;
        System.out.print((s1 == s3) + "" + (s1 == s5) + "" + "" (s3 == s5));
    }
}

输出为false false false 甚至将s3声明为最终表达式!为什么?

2 个答案:

答案 0 :(得分:1)

If pool memory already has an object with similar content, then if we try to create the same object with different reference variable then only a new reference variable is created, NO NEW OBJECT IS CREATED.eg;

在一般情况下,实际上并非如此。您所描述的内容称为String interninginterned字符串始终是引用 - 等于具有相同内容的任何其他实习字符串 - 这基本上是intern的保证。 (来自String.intern上的docs接下来,对于任何两个字符串s和t,当且仅当s.equals时,s.intern()== t.intern()为真(t)是真的。)。如果我要从一个常量字节数组创建2个字符串,那么即使它们共享内容,它们也会是不同的对象。

JLS进一步指明:
此外,字符串文字始终引用类String的相同实例。这是因为字符串文字 - 或者更常见的是作为常量表达式(第15.28节)的值的字符串 - 被“实例化”以便使用String.intern方法共享唯一实例。

因此,为什么你得到字符串文字的相等性,以及任何值为[a]常量表达式的东西。

那么,这个常量表达式是什么?好吧,根据JLS,这些是文字,简单名称(§6.5.6.1)引用常量变量,各种非String内容和+表达式,但是只要+的两个操作数都是constant expressions String对象是新创建的(§12.5),除非表达式是常量表达式(§15.28)。) 。所以这意味着,除非+两个侧的字符串都是文字,否则最终字符串的值为常量表达式或满足其他条件之一(就像来自原始常量的强制转换),将创建一个新对象。

答案 1 :(得分:1)

这是因为

1)由常量表达式计算的字符串(第15.28节)在编译时计算,然后视为文字。

2)在运行时通过串联计算的字符串是新创建的,因此是不同的。

以下是一个例子:

    String s7 = "77";
    String s8 = "77";

    String s10 = "7";
    String s11 = "7";

    String s9 = s10+s11;
    String s12 = "7"+"7";

    //printing the address
    System.out.println(System.identityHashCode(s7));
    System.out.println(System.identityHashCode(s8));
    System.out.println(System.identityHashCode(s9));
    System.out.println(System.identityHashCode(s12));

    System.out.println(s7==s9);
    System.out.println(s7==s12);

<强> 输出:

705927765
705927765
366712642  ---> address is different
705927765
false
true

虽然我刚才也经历过这个问题。但这是我的假设:

除了String s9 = s10+s11;之外的所有文字都是在编译时计算的。这就是为什么我们得到不同的地址。

关注String literals javadoc了解详情。