概念:
String.intern()是一個(gè)native方法,它的作用是:如果字符串常量池中已經(jīng)包含了一個(gè)等于此String對(duì)象的字符串,則返回代表池中這個(gè)字符串的String對(duì)象;否則,將此String對(duì)象包含的字符串添加到常量池中,并且返回此String對(duì)象的引用。
上述的黑體部分,在jdk1.6和1.7(含以上)中的表現(xiàn)形式是不同的。
1.jdk1.6中,字符串常量池是放在于永久代中的,這個(gè)是完全區(qū)分于堆內(nèi)存的。intern()方法會(huì)把首次遇到的字符串實(shí)例復(fù)制一個(gè)到永久代中,返回的也是永久代中這個(gè)字符串實(shí)例的引用。
2.jdk1.7中,字符串常量池已經(jīng)被放在了堆中,而intern()方法不會(huì)在復(fù)制實(shí)力,只是在常量池中記錄首次出現(xiàn)的實(shí)例引用,因此對(duì)堆內(nèi)存中的String引用使用intern()方法,常量池中并不會(huì)出現(xiàn)對(duì)應(yīng)的字符串,而是指向了堆內(nèi)存中的實(shí)例。
代碼分析:
public class Test4 {
public static void t1(){
//實(shí)例s1存在于堆內(nèi)存中,常量池中并不存在該字符串“java”
String s1 = new StringBuilder("mjp").append("cmm").toString();
//s1 intern會(huì)檢查常量池是否有“mjpcmm”,這里不存在,所以直接在常量池中記錄該引用,即s2指向了s1,所以s1==s2返回true
String s2 = s1.intern();
System.out.println(s1 == s2);//這里打印出true
}
public static void t2(){
//先再字符串常量池中創(chuàng)建了mjpcmm這個(gè)常量,s保存對(duì)應(yīng)常量池的引用地址
String s = "mjpcmm";
//實(shí)例s1存在于堆內(nèi)存中,所以這里有兩個(gè)引用,s指向常量池,s1則指向堆內(nèi)存
String s1 = new StringBuilder("mjp").append("cmm").toString();
//s1 intern會(huì)檢查常量池是否有“mjpcmm”,這里已經(jīng)存在,所以直接返回該引用,即s2指向了s,所以s==s2返回true,s1==s2返回false
String s2 = s1.intern();
System.out.println(s == s2);//這里打印出true
System.out.println(s1 == s2);//這里打印出false
}
public static void main(String[] args) {
// t1();
t2();
}
}