字符串常量池和String.intern()方法在jdk1.6、1.7、1.8中的变化
字符串常量池是运行时常量池
在JDK1.6中,它在方法区中,属于“永久代”.
在JDK1.7中,它被移除方法区,放在java堆中。
在JDK1.8中,取消了“永久代”,将常量池放在元空间,与堆独立。
[code]public class RuntimeConstantPoolOOM { public static void main(String[] args) { String str1 = new StringBuffer("计算机").append("shuju").toString(); String str2= new StringBuffer("计算机").append("shuju").toString(); System.out.println(str1.intern()==str1);//true System.out.println(str2==str2.intern());//false } }
以上是jdk1.7测试效果。
String.intern()在JDK1.6中,会先判断常量池中是否存在当前字符串,不存在就会将当前字符串复制到常量池。并返回常量池中的字符串引用。
而在JDK1.7后,会先判断常量池中是否存在当前字符串,不存在时不会将当前字符串复制到常量池,只当前字符串的引用。如果存在,也不会改变存在的引用,及只会保存首次存储的字符串的引用。如上代码所示,常量池保存的是str1的引用,即使str2调用intern()方法,返回的也是str1的引用。
从以上代码也可以看出,调用toString方法只会在堆中创建字符串对象。
字符串创建各种状态如下:
1.只在常量池上创建常量
String a1 = "AA";
2.只在堆上创建对象:调用toString方法或者+
String a2 = new String("A") + new String("A");
3.在堆上创建对象,在常量池上创建常量
String a3 = new String("AA");
4.在堆上创建对象,在常量池上创建引用
String a4 = new String("A") + new String("A");//只在堆上创建对象AA
a4.intern();//将该对象AA的引用保存到常量池上
参考:https://blog.csdn.net/u013366617/article/details/83618361
- String.intern() 方法__jdk1.6与jdk1.7的不同
- jdk1.6 1.7 1.8 运行时常量池位置的变化
- jdk1.6 1.7 1.8 运行时常量池位置的变化
- JDK1.5/1.6/1.7/1.8 java.util下的集合类底层实现的变化
- JDK1.8、JDK1.7、JDK1.6区别看这里
- jdk源码剖析四:JDK1.7升级1.8 HashMap原理的变化
- jdk1.6 的 HashMap 源码分析及1.7,1.8的主要更改
- 启动weblogic服务时,报此时不应有“1.6(1.7)jdk”解决方法
- 关于安装版JDK1.8或1.7更改多个JDK环境变量不生效的解决方法
- ConcurrentHashMap从jdk1.7到jdk1.8的变化
- jdk1.5 jdk1.6 jdk1.7 jdk1.8 下载地址
- jdk1.5 jdk1.6 jdk1.7 jdk1.8 特性
- ConcurrentHashMap从jdk1.7到jdk1.8的变化
- 安装jdk1.8后,修改%JAVA_HOME%为jdk1.6的路径,但运行java -version没有变化
- 关于安装版JDK1.8或1.7更改多个JDK环境变量不生效的解决方法
- 【图解JDK源码】HashMap的容量大小增长原理(JDK1.6/1.7/1.8)
- mac x Yosemide(10.10) 下安装 jdk 1.7 (jdk 1.8)的方法
- 牛客网Java刷题知识点之HashMap的实现原理、HashMap的存储结构、HashMap在JDK1.6、JDK1.7、JDK1.8之间的差异以及带来的性能影响
- jdk1.7和jdk1.8的String的getByte方法的差异
- jdk1.6,jdk1.7,jdk1.8安装共存问题