????????在java8中调俘,String調(diào)用了intern()方法伶棒,如果常量池里面有此字符串,那么返回此字符串脉漏,如果有引用苞冯,則返回這個(gè)引用;如果沒(méi)有就將這個(gè)字符串的引用或者字符串(有引用放引用)放入常量池侧巨。比如下面代碼
String str1=new String("a")+new String("b");
str1.intern();//這句話之后字符串池存著“ab”的引用
String str2="ab";//從字符串常量池找字符串或者指向字符串的引用
System.out.println(str1==str2);//true
這里解釋一下:
? ? ? ? ①執(zhí)行完new String("a")+new String("b")之后舅锄,堆中有a、b司忱、ab對(duì)象皇忿,(但是請(qǐng)注意字符串常量池卻沒(méi)有ab字符串,類似的還有new String("XX")+"YY"或者str+“ZZ”坦仍,(append相加也不會(huì))簡(jiǎn)單來(lái)說(shuō)相加的形式只要其中有非字面量鳍烁,那么就不會(huì)在常量池創(chuàng)建這個(gè)相加的結(jié)果字符串)
? ? ? ? ②之后執(zhí)行str1.intern()方法,因?yàn)樽址A砍貨](méi)有“ab”的引用或者字符串繁扎,那么將這個(gè)引用放入字符串常量池幔荒,這里就是str1的引用地址
? ? ? ? ③接著執(zhí)行str2=“ab”,現(xiàn)在常量池找是否有“ab”的引用或者字符串梳玫,在第二步中爹梁,“ab”的引用已經(jīng)放到了字符串常量池,那么這里就會(huì)直接返回這個(gè)引用提澎,即str1的指向地址姚垃,所以str1和str2指向同一個(gè)地址,引用相同盼忌,返回true
再來(lái)說(shuō)說(shuō)下面情況
String str7=new String("hello");
str7.intern();
String str8="hello";
System.out.println(str7==str8);//false
????在執(zhí)行new String("hello")的時(shí)候积糯,除了在堆中創(chuàng)建hello對(duì)象外,字符串常量池也會(huì)創(chuàng)建一個(gè)hello字符串谦纱,所以在str7.intern()的時(shí)候看成,并沒(méi)有像第一種情況一樣把引用放入常量池,因?yàn)橐呀?jīng)有了跨嘉,str8=“hello”绍昂,將str8指向字符串常量池的“hello”字符串,str7指向堆中的引用偿荷,所以str7和str8引用不同窘游,返回false