????????在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字符串,類(lèi)似的還有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