String::intern()是一个本地方法,它的作用是如果字符串常量池中已经包含一个等于此String对象的字符串,则返回代表池中这个字符串的String对象的引用;否则,会将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。
先看一下下面这段代码
public class StringInternTest {
public static void main(String[] args) {
String str1 = new String("计算机")+new String("软件");
System.out.println(str1.intern() == str1);
}
}
这段代码咋JDK6中运行,会得到false,而在JDK7及以上运行,会得到true。产生差异的原因是:
在JDK 6中,intern()方法会把首次遇到的字符串实例拷贝到永久代的字符串常量池中存储,返回的也是永久代里面这个字符串实例的引用,str1.intern()方法返回的就是字符串常量池中的对象引用,而str1是在java堆上,两者自然不等。
然而到了JDK7,原本存放在方法区里的字符串常量池被移至Java堆之中,intern()方法实现就不需要再拷贝字符串的实例到永久代了,既然字符串常量池已经移到Java堆中,那只需要在常量池里记录一下首次出现的实例引用即可,因此str1.intern()返回的引用和由str这个字符串实例就是同一个。
再看一下代码:
ublic 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");
s3.intern(); //jdk6中把s3拷贝一份到常量池;而jdk7中只需在常量池记录s3对象的引用
String s4 = "11"; //在jdk6中指向常量池中s3的拷贝对象;而jdk7中由于常量池中记录了"11"这个字符串对象的引用,所以s4最终指向s3所指向的对象
System.out.println(s3 == s4);
}
打印结果是:
jdk6 下false false
jdk7 下false true
网友评论