一道偏门的面试题

Scroll Down
public class String58Demo {
    public static void main(String[] args) {
        String str1 = new StringBuilder("58").append("tongcheng").toString();
        System.out.println(str1);
        System.out.println(str1.intern());
        System.out.println(str1 == str1.intern());

        System.out.println("~~~~");
        String str2 = new StringBuilder("ja").append("va8").toString();
        System.out.println(str2);
        System.out.println(str2.intern());
        System.out.println(str2 == str1.intern());
    }
}

请问输入的str1==str1.intern();
str2==str2.intern();
结果是什么

先说结果:
1.str1==str1.intern() 结果是true
2.str2==str2.intern() 结果是false

原因是啥呢???
String的intern()方法作用是找字符串常量池里是否有对应字符串,如果有就引用,如果没有就创建。

为啥java这边会返回false.两个java的地址不同。
原因是因为在sun.misc.Version.class中通过本地加载到内存中。
看具体代码
image.png

System这个类在初始化的时候调用的sun.misc.Verison.init();
image.png

当然,如果你用的是openJDK那么结果就是两个true...
如果是JDK6,那么结果是两个false,JDK7会得到一个ture一个false.

深入理解Java虚拟机 第三版 原文

产生差异的原因是,jdk6中,intern()方法会把首次遇到的字符串实例复制到永久代的字符串常量池中存储,返回的也是永久代的这个字符串,而由StringBuilder创建的字符串对象实例在Java堆上,所以必然不可能是同一个引用。

jdk7的intern()就不再需要拷贝字符串到永久代了,既然字符串常量池已经移到Java堆中,那么只需要在常量池中记录一下首次出现到实例引用即可。