为什么这些字符串的str == str.intern()结果不同?

sid*_*ide 15 java string string-interning

public static void main(String[] args) {
    String str1 = new StringBuilder("???").append("??").toString();
    System.out.println(str1.intern() == str1);
    String str2 = new StringBuffer("ja").append("va").toString();
    System.out.println(str2.intern() == str2);
}
Run Code Online (Sandbox Code Playgroud)

结果:

 true
 false   
Run Code Online (Sandbox Code Playgroud)

第一个打印true,第二个打印false.为什么结果不同?

Sot*_*lis 20

行为的差异与StringBuilder和之间的差异无关StringBuffer.

String#intern()它返回的状态的javadoc

调用实习方法时,如果池已包含Stringequals(Object) 方法确定的此对象相等的字符串,则返回池中的字符串.否则,将此 String对象添加到池中,并 返回对此String对象的引用.

String从创建

String str2 = new StringBuffer("ja").append("va").toString();
Run Code Online (Sandbox Code Playgroud)

是一个String不属于游泳池的全新品牌.

对于

str2.intern() == str2
Run Code Online (Sandbox Code Playgroud)

要返回false,intern()调用必须返回不同的参考值,即.String "java"已经在游泳池里了.

在第一次比较中,String"计算机软件" 在调用之前不在字符串池中intern().intern()因此返回与存储的相同的引用str2.因此引用相等str2 == str2返回true.

  • @SotiriosDelimanolis:我想验证它是否确定,实际上,堆转储显示它在那里.http://i.imgur.com/Fv5pbFV.png (3认同)
  • @JeroenVannevel引用_否则,此String对象被添加到池中并返回对此String对象的引用._不够好? (2认同)
  • @JeroenVannevel你误解了.字符集无关紧要.如果池中有一个相等的`String`,`intern()`返回对**`String`的引用,否则返回对**this**`String`的引用.在第一种情况下,它返回了对**this**`String`的引用,这就是为什么`true ==(this == this)`. (2认同)

Ell*_*sch 5

因为您的分配不会从内部缓冲池中重新读取,并且Java String是不可变的。考虑

String str1 = new StringBuilder("???").append("??").toString();
String str1a = new String(str1); // <-- refers to a different String 
str1 = str1.intern();
str1a = str1a.intern();
System.out.println(str1a == str1);
String str2 = new StringBuffer("ja").append("va").toString();
String str2a = new String(str2); // <-- refers to a different String 
str2 = str2.intern();
str2a = str2a.intern();
System.out.println(str2a == str2);
Run Code Online (Sandbox Code Playgroud)

输出是(如您预期的那样)

true
true
Run Code Online (Sandbox Code Playgroud)

  • @side任何时候两个对象与'=='相等时,它们具有相同的引用。 (2认同)