当调用intern方法时,如果常量池中已经存在该字符串,则返回池中的字符串;否则将此字符串添加到常量池中,并返回字符串的引用。
作用
1、重用String对象,以节省内存消耗。
2、多次比较字符串值时,intern()后字符串可以直接 == 进行比较。比equals()要快
举个例子
class Test {
public static void main(String args[]) {
String s1 = new StringBuilder().append("String").append("Test").toString();
System.out.println(s1.intern() == s1);
String s2 = new StringBuilder().append("ja").append("va").toString();
System.out.println(s2.intern() == s2);
}
}
1、JDK6的执行结果:false false
在JDK6中,常量池在永久代分配内存,永久代和Java堆的内存是物理隔离的,执行intern方法时,如果常量池不存在该字符串,虚拟机会在常量池中复制该字符串,并返回引用,所以需要谨慎使用intern方法,避免常量池中字符串过多,导致性能变慢,甚至发生PermGen内存溢出
2、JDK8的执行结果:true false
在JDK8中,常量池已经在Java堆上分配内存,执行intern方法时,如果常量池已经存在该字符串,则直接返回字符串引用,否则复制该字符串对象的引用到常量池中并返回,所以在JDK7中,可以重新考虑使用intern方法,减少String对象所占的内存空间
对于变量s1,常量池中没有 "StringTest" 字符串,s1.intern() 和 s1都是指向Java对象上的String对象。
对于变量s2,常量池中一开始就已经存在 "java" 字符串(为什么一开始就有,可以阅读《深入理解java虚拟机》String.intern()探究),所以 s2.intern() 返回常量池中 "java" 字符串的引用。
参考文章
java中String.intern() 方法到底是干啥的?