我现在正在学习Java,我读了以下问题:What is Java String interning? - Stack Overflow但我阅读了其他文章,其中提供了一些我不理解的示例:
public static void main(String[] args) {
String str2 = new String("str") + new String("01");
str2.intern();
String str1 = "str01";
System.out.println(str2 == str1); //true
String s4 = new String("1");
s4.intern();
String s5 = "1";
System.out.println(s4 == s5); //false
String s = new StringBuilder("aa").append("bb").toString();
String s2 = new StringBuilder("cc").toString();
System.out.println(s.intern() == s); //true
System.out.println(s2.intern() == s2); //false
}
Java 11中的结果(在Java 8中应相同):
true
false
true
false
我不知道为什么结果不同,我想这都是真的。有人可以解释吗?
让我们看看intern
的实际作用(强调我的意思:
当调用intern方法时,如果池已经包含与equals(Object)方法确定的等于此String对象的字符串,则返回池中的字符串。 否则,此String对象将添加到池中,并返回对此String对象的引用。
运行此代码时:
intern
字符串池仅包含str2.intern();
和"str"
。 "01"
是str2
,它不在字符串池中,因此"str01"
引用的对象也添加到了字符串池中。因此,到达下一行时,由于str2
已在池中,因此"str01"
将引用与str1
相同的对象。
请注意,str2
之所以不是,是因为str2 == str1
以某种方式更改了intern
指向的对象。它不执行对str2
执行任何操作。字符串毕竟是不可变的。
现在我们可以理解第一个str2
。在该行中:
false
由于字符串文字String s4 = new String("1");
,"1"
被添加到字符串池。请注意,添加到字符串池的对象与"1"
引用的对象不同。现在,您调用s4
,它对s4.intern()
没有任何作用,并且返回字符串池中的对象。但是您忽略了返回值。这就是s4
和s4 != s5
的原因。
s4.intern() == s5
的原因要简单得多-s2.intern() != s2
在字符串池中引用的对象与s2
不同! "cc"
应该返回字符串池中的对象,所以当然它不是同一对象!