在周志明的《深入理解java虚拟机》,2nd,p57中有一部分代码
String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == str2);
对照着intern()看了api源码上的javadoc注释
public native String intern();
个人理解是:
如果调用intern之前字符串已存在,返回字符串对象,否则返回字符串引用。“首次出现”返回引用。
讲到在jdk 7之前的版本中,intern() 会把首次遇到的String实例复制到永久代中,返回的是永久代中String实例的引用。由StringBuilder创建的String实例在堆上,所以不是同一个引用,返回false。
按照jdk历史版本的内存区域分布图,得知jdk 7之前的执行结果为
false false
jdk 7及以后的执行结果为
true false
但是不太理解书籍里讲到的
“java”这个字符串在执行StringBuilder的toString()之前已经出现过,字符串常量池已经有它的引用了,不符合“首次出现”的原则。
感觉这里作者埋坑了,在看到3rd版里讲到这个地方,说读者有这个疑问,给了注释讲到说是在sun.misc.Version中已经存在,提到了知乎里的作者RednaxelaFX在https://www.zhihu.com/question/51102308/answer/124441115
里做了讲解, 讲的很好。



