java 两个String对象相加的结果在内存中的分布是怎样的?

class Main {
    public static void main(String[] args) {
        String a="11";
        String b="11";
        String c=a+b;
        System.out.println(c==c.intern());
        c=b+b;
        System.out.println(c==c.intern());
    }
}

第一个结果是True,第二个结果是false
我的理解是,两个String对象相加的过程中,用一个StringBuilder进行两次append(“11”),然后调用toString返回一个String对象,也就是c指向堆中的一个对象,该对象中储存一个地址指向常量池中的“1111”。c指向堆中地址,c.intern()指向常量池地址,所以结果是false,但是不能理解为什么第一个结果是True

找到了,是intern()的问题 ,把c=a+b 和c=b+b调换结果也是一样的。是因为intern()在调用时首先检查字符串常量池中有没有“1111”,如果有的话,返回“1111”在常量池中的地址,如果没有的话,将c的地址拷贝一份到常量池中,也就是说,常量池中的“1111”对应了一个堆中的地址,即c的地址,调用常量池中“1111”会返回c在堆中的地址,所以第一个c==c.intern返回的是true。在第二个c赋值时new了一个堆中地址,此时c.intern返回的是常量池中“1111”对应的地址,也就是c在堆中的第一个地址,和第二个地址不同,返回false。

【以下回答由 GPT 生成】

Java中两个String对象相加的结果在内存中的分布是怎样的?

在Java中,当两个String对象相加时,其结果在内存中的分布如下:

  1. 创建两个String对象 ab,它们的值都是 "11"。
  2. 通过 + 运算符将 ab 相加,生成一个新的String对象 c
  3. c 指向存储在堆中的一个新对象,该对象包含相加后的字符串 "1111"。
  4. 通过 c.intern() 方法,将 c 对象的引用加入字符串常量池中。
  5. 打印 c == c.intern() 的结果表明 c 对象的引用是否与字符串常量池中的地址相同。

接下来,解释为什么第一个结果是True,而第二个结果是false。

第一个结果是True,表示 c 的引用和字符串常量池中的地址是相同的,这是因为: - c 对象被加入了字符串常量池,因此 c.intern() 返回字符串常量池中的地址。 - c 对象的引用与字符串常量池中的地址相同,所以 c == c.intern() 返回True。

第二个结果是false,表示 c 的引用和字符串常量池中的地址不同,这是因为: - 当 c 的值被更改为 "1111",该字符串在字符串常量池中并不存在相同的地址。 - 因此, c.intern() 返回的是字符串常量池中新创建的地址。 - c 对象的引用与字符串常量池中的地址不同,所以 c == c.intern() 返回False。

综上所述,第一个结果为True,是因为字符串常量池中已经有了相同值的引用;而第二个结果为false,是因为字符串常量池中没有相同值的引用。

请注意,== 操作符比较的是对象的引用,而不是内容。如果要比较字符串的内容是否相等,应使用 equals() 方法。

希望以上解答能够帮助您理解Java中两个String对象相加结果在内存中的分布。如果还有任何疑问,请随时提问。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^