String类的intern()

来源:互联网 发布:任亮 java 编辑:程序博客网 时间:2024/06/06 21:43

简介

JVM运行时数据区中的方法区有一个常量池,JDK1.6之后(即JDK1.7)常量池被放在了堆空间,常量池位置的不同影响着String 的intern方法的表现。
intern()方法设计初衷,重用String对象,以节省内存消耗。

intern()

String s = new String("1"); String s1 = "1";s.intern();System.out.println(s1 == s);String s2 = new String("1") + new String("2");s2.intern();String s3 = "12";System.out.println(s2 == s3);

输出结果:
JDK1.6以及以下:false false
JDK1.7以及以上:false true

JDK版本

在JDK1.6以及以下的版本中,常量池是放在Perm区(方法区)。
使用“”声明的字符串都是会直接在字符串常量池中生成的,而new处理的String对象是放在堆空间的。所以两者的内存地址肯定是不同的,即便调用intern方法也是不影响的。

s.intern()在JDK1.6的作用:检查字符串池中是否含有s字符串,如果有,直接返回池里的字符串;如果不存在,该方法会把s添加到字符串池中后再返回它的引用。

而在JDK1.7中,常量池中可以直接储存堆中的引用,不需要再存储一份对象。

代码注释解析

例1

   String s1 = "1"; //常量池   String s2 = new String("1");//堆   s2.intern(); //拷贝时发现已经存在,没必要拷贝,实际无任何影响。   System.out.println( s1 == s1 );//false

例2

// String s1 = "1";   String s2 = new String("1");  //新建两个对象,常量池1个,堆1个    //常量池存在1    s2.intern();    System.out.println("1" == s2); //false

例3

String s2 = new String("1")+new String("2");s2.intern();//常量池没有"12"//jdk1.6拷贝对象到常量池,返回新引用,但s2不变还是指向堆,s2.intern()!=s2//jdk1.7中,常量池不需要再储存一份对象了,拷贝引用不是拷贝对象,也就是说s2.intern == s2,会返回true。//前提是常量池中没有这个串(或其引用),如果已经有了不会发生任何拷贝,只会返回池中引用。String s1 = "12"; //使用常量池已有,得到引用。System.out.println(s1 == s2)//1.6false,1.7 true
原创粉丝点击