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对象相加时,其结果在内存中的分布如下:
a
和 b
,它们的值都是 "11"。+
运算符将 a
和 b
相加,生成一个新的String对象 c
。c
指向存储在堆中的一个新对象,该对象包含相加后的字符串 "1111"。c.intern()
方法,将 c
对象的引用加入字符串常量池中。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对象相加结果在内存中的分布。如果还有任何疑问,请随时提问。