今天准备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:
JDK9:
看了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吧。