【Java】关于String.intern()函数在JDK8 和 JDK9 下结果不同的问题

今天准备opentalk资料的时候,无意间发现一段很有意思的代码,特此记录一下:

/**
 * @author dxc
 * @date 2018/11/4 
 */
public class StringInternTest {
    public static void main(String[] args) {
        String s = new String("1");
        s.intern();
        String s2 = "1";
        System.out.println(s == s2);

        String s3 = new String("1") + new String("1");
        //String s3 = "1" + "1";
        s3.intern();
        String s4 = "11";
        System.out.println(s3 == s4);
        System.out.println(s3.equals(s4));
    }
}

上述代码在JDK8(“1.8.0_172”)的环境下运行结果是:

false
true
true

在JDK9(“9.0.1”)的环境下运行结果是:

false
false
true

感觉很奇怪,JDK9按道理不应该和JDK8的结果一致么?难道JDK9和JDK8两个版本的String.intern()实现机制不同?我确定我的java版本没有搞错呢。暂时记录一下这个问题,考虑到JDK9不是长期维护版本,JDK11已经发布,后面要看一下在JDK11的环境下这段代码是什么结果。

stackoverflow提问地址:https://stackoverflow.com/questions/53141338/why-does-string-intern-return-different-results-under-jdk8-and-jdk9

所使用的两个java version :

JDK8:

【Java】关于String.intern()函数在JDK8 和 JDK9 下结果不同的问题_第1张图片

JDK9:

【Java】关于String.intern()函数在JDK8 和 JDK9 下结果不同的问题_第2张图片

       看了stackoverflow上的回答,应该是JDK9中的"11"已经存在常量池中了,而JDK8中"11"不在常量池中导致的。把"11"换成其他胡乱的字符串,程序运行结果是和JDK8一致的(false-true-true);如果把"11"换成常量池中已有的"java"字符串,则返回结果和"11"一致,验证了这种结论。

以下代码,JDK8和JDK9都返回:

false
false
true

代码:

/**
 * @author dxc
 * @date 2018/11/4 0004
 */
public class StringInternTest {
    public static void main(String[] args) {
        String s = new String("1");
        s.intern();
        String s2 = "1";
        System.out.println(s == s2);

        String s3 = new String("ja") + new String("va");
        //String s3 = "1" + "1";
        s3.intern();
        String s4 = "java";
        System.out.println(s3 == s4);
        System.out.println(s3.equals(s4));
    }
}

PS:JDK 9 和 JDK 10 都不是长期维护版本,长期维护的JDK 11版本 已经发布,9和10已经成为历史了。。。自己玩的话,还是早点换成最新的JDK11吧。

你可能感兴趣的:(Java)