????????在java8中,String調用了intern()方法,如果常量池里面有此字符串,那么返回此字符串,如果有引用,則返回這個引用;如果沒有就將這個字符串的引用或者字符串(有引用放引用)放入常量池。比如下面代碼
String str1=new String("a")+new String("b");
str1.intern();//這句話之后字符串池存著“ab”的引用
String str2="ab";//從字符串常量池找字符串或者指向字符串的引用
System.out.println(str1==str2);//true
這里解釋一下:
? ? ? ? ①執行完new String("a")+new String("b")之后,堆中有a、b、ab對象,(但是請注意字符串常量池卻沒有ab字符串,類似的還有new String("XX")+"YY"或者str+“ZZ”,(append相加也不會)簡單來說相加的形式只要其中有非字面量,那么就不會在常量池創建這個相加的結果字符串)
? ? ? ? ②之后執行str1.intern()方法,因為字符串常量池沒有“ab”的引用或者字符串,那么將這個引用放入字符串常量池,這里就是str1的引用地址
? ? ? ? ③接著執行str2=“ab”,現在常量池找是否有“ab”的引用或者字符串,在第二步中,“ab”的引用已經放到了字符串常量池,那么這里就會直接返回這個引用,即str1的指向地址,所以str1和str2指向同一個地址,引用相同,返回true
再來說說下面情況
String str7=new String("hello");
str7.intern();
String str8="hello";
System.out.println(str7==str8);//false
????在執行new String("hello")的時候,除了在堆中創建hello對象外,字符串常量池也會創建一個hello字符串,所以在str7.intern()的時候,并沒有像第一種情況一樣把引用放入常量池,因為已經有了,str8=“hello”,將str8指向字符串常量池的“hello”字符串,str7指向堆中的引用,所以str7和str8引用不同,返回false