Java8 String.intern()

在 JAVA 語言中有 8 中基本類型和一種比較特殊的類型 String 。這些類型爲了使他們在運行過程中速度更快,更節省內存,都提供了一種常量池的概念。常量池就類似一個 JAVA 系統級別提供的緩存。
在 JDK6 及以前的版本中,運行時常量池是放在永久代。在 JDK7 及之後的版本中,運行時常量池從永久代移到堆區域

String 類型的常量池比較特殊。它的主要使用方法有兩種:
直接使用雙引號聲明出來的 String 對象會直接存儲在常量池中
如果不是用雙引號聲明的 String 對象,可以使用 String 提供的 intern 方法。 intern 方法會從字符串常量池中查詢當前字符串是否存在,若不存在就會將當前字符串放入常量池中
光看這兩句話在使用上還是有問題,下面配合例子講解

1.直接用雙引號創建字符串
String str1 = "test";
String str2 = "test";
//str1 == str2 ? true
System.out.println("str3 == str4 ? "+ (str1 == str2));

直接使用雙引號聲明出來的 String 對象常量會直接存儲在常量池中
所以str2返回的是常量池中的常量"test"

2.new String 創建字符串
String str3 = new String("tony");
str1.intern();
String str4 = "tony";
//str3 == str4 ? false
System.out.println("str3 == str4 ? " + (str3 == str4));

這個new String要這麼看,分成兩步
s1 = “tony”;
s2 = new String(s1);
s2.intern();
s4 = “tony”
第一句如第一種情況,常量池中檢查,沒有,把常量"tony"放進常量池中;s2 new String必然會在jvm堆中創建了一個實例,s2.intern()從字符串常量池中查詢當前字符串是否存在,存在不作處理;s4在常量池中有常量"tony",拿過來
所以結果是false

3.new String 相加
String str5 = new String("good") + new String("morning");
str5.intern();
String str6 = "goodmorning";
//str5 == str6 ? true str5 == str5.intern() ? true
System.out.println("str5 == str6 ? " + (str5 == str6) + " str5 == str5.intern() ? " + (str5 == str5.intern()));

和第二種情況不同,第一句會分別把不在常量池的"good"和"morning"兩個常量加入常量池,拼接起來"goodmorning"不在常量池,str5.intern()檢查常量池是否有字符串"goodmorning",沒有,把引用添加到常量池中,str6檢查常量池有字符串"goodmorning",返回它的引用,所以兩個判斷的結果都是true

4.總結

String.intern()是給不是用雙引號聲明的 String 對象用的,使用後
如果常量池已有該字符串
1.若是常量,返回常量
2.若是引用,返回該引用
如果沒有該字符串
把引用添加到常量池中


以上是一點對string.intern()的理解,歡迎大家交流指正
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章