在jvm这本书里看到如下代码;
public class RuntimeConstantPoolOOM{
public static void main(String[] args){ 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);
}
}
首先说一下 String中的inter()方法是一个native方法
这段代码在JDK1.6 中运行时,会得到两个false,而在JDK1.7中运行时,会得到一个true和一个false,产生差异的原因是:在1.6中 ,inter()方法会把第一次遇到的字符串实例复制到 字符串常量池中,返回的也是常量池中的实例的引用,而由StringBuilder创建的字符实例在java堆上,所以必然不是同一个引用,将返回false;
但是到了 JDK1.7以后大部分的虚拟机的实现是 inter()方法不再复制实例,而只是在常量池中记录首次出现的实例的引用,因此inern()返回的引用和StringBuilder创建的实例的引用是同一个,之所以结果是true 是因为在常量池中已经有了"java"这个字符串的的引用了,不符合首次出现 所以为false;
"java"这个字符串应该是在java虚拟加载基础包.rt.jar时被加载进来的!!
|
|