public class Demo {
public static void main(String[] args) {
String str1 = new StringBuilder("ab").append("cd").toString();
System.out.println(str1);
System.out.println(str1.intern());
System.out.println(str1 == str1.intern()); // true JDK 1.8
System.out.println("------------");
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2);
System.out.println(str2.intern());
System.out.println(str2 == str2.intern()); // false JDK 1.8
}
}
注意点1:"java"这个字符串已经在系统中创建过
java.lang.System -- initializeSystemClass() -- sun.misc.Version.init();
sun.misc.Version这个类中的一个静态常量的值为"java"
注意点2:上述代码在JDK1.6和JDK1.7+版本下的执行结果不同
JDK版本 | abcd(首次出现) | java(再次出现) |
---|---|---|
1.6 | false | false |
1.7+ | true | false |
JDK1.6:
首次出现时,拷贝对象,返回池中对象引用;
再次出现时,直接返回池中对象引用。
首次拼接出"abcd"时,堆中创建该对象(1),池中拷贝该对象(2),返回对象(2)的引用;
str1指向对象(1);
str1.intern()指向对象(2);
所以false
再次出现"java"时,池中已有该对象,直接返回池中该对象的引用;
str2指向新建的对象;
str2.intern()指向池中的对象(即首次出现的对象);
所以false
JDK1.7+:
首次出现时,池中引用指向对象,返回池中引用(首次出现的对象的引用)
再次出现时,直接返回池中引用(首次出现的对象的引用)
首次拼接出"abcd"时,堆中首次创建该对象(1),池中记录该对象(1)的引用并返回;
str1指向对象(1);
str1.intern()指向对象(1);
所以true
再次出现"java"时,池中已记录该对象(首个"java"对象)的引用,直接返回池中该引用;
str2指向新建的对象;
str2.intern()指向池中引用指向的对象(首个"java"对象);
所以false