1. 程式人生 > 實用技巧 >String 簡述及intern方法

String 簡述及intern方法

  https://docs.oracle.com/javase/8/docs/api/java/lang/String.html

  在JAVA中有8種基本型別和一種特殊字元型別:String。這些型別為了執行更快,更節省記憶體,使用了常量池的概念。

  String宣告為final,表示不可繼承,所有的屬性也是final型別。字串常量:string一經建立值便不可修改。由於它的不可變性,因此string相關的拼接,擷取等操作都會產生新的物件。String底層使用char陣列方式進行儲存。

  常見生成string方式:

  1、String s = new String("abc"); 建立了二個物件:1、第一個物件 "abc"對應常量池中;第二個物件 在JAVA heap中的String物件。

   2、String a = "11";  宣告使用雙引號直接儲存到常量池中。

   3、String.valueOf(1);  底層使用new String(char[])的方式實現轉換

  String#intern方法

  native String intern():目的是提示 JVM 把相應字串快取起來,以備重複使用。。

  intern() 是一種顯式排重的機制。需要使用者顯式呼叫它,這樣一是不方便,二是每次顯式比較麻煩。

  要注意的是,String的String Pool是一個固定大小的Hashtable,預設值大小長度是1009,如果放進String Pool的String非常多,就會造成Hash衝突嚴重,從而導致連結串列會很長,而連結串列長了後直接會造成的影響就是當呼叫String.intern時效能會大幅下降(因為要一個一個找)。


在 jdk6中StringTable是固定的,就是1009的長度,所以如果常量池中的字串過多就會導致效率下降很快。

在jdk7中,StringTable的長度可以通過一個引數指定: -XX:StringTableSize=99991

 1  public static void main(String[] args)  {
 2         String s1 = new String("1");
 3         String s2 = "1";
 4         s1.intern();
 5         System.out.println(s1 == s2);
 6 
 7
String s3 = new String("1") + new String("2"); 8 String s4 = "12"; 9 s3.intern(); 10 System.out.println(s3 == s4); 11 }

輸出結果: false false

程式碼行7:生成兩個物件,分別對應常量池"1","2", JAVA heap中的s3引用指向的物件。 s3引用指向物件的內容是"12",但是此時常量池中沒"12"物件。"Java語言為字串連線運算子(+)以及將其他物件轉換為字串提供了特殊的支援。字串連線是通過StringBuilder(或StringBuffer)類及其append方法實現的。字串轉換是通過toString方法實現的"

程式碼行8:s4是顯式宣告,直接向常量池查詢不到,則建立物件。

程式碼行9:intern()返回字串物件的規範表示形式。在呼叫intern方法時,如果池中已經包含了由equals(object)方法確定的與該字串物件相等的字串,則返回池中的字串。否則,該字串物件將被新增到池中,並返回對該字串物件的引用。

如果s4 變換下位置

 1  public static void main(String[] args)  {
 2         String s = new String("1");
 3         String s2 = "1";
 4         s.intern();
 5         System.out.println(s == s2);
 6 
 7         String s3 = new String("1") + new String("2");
 8         s3.intern();
 9         String s4 = "12";
10         System.out.println(s3 == s4);
11     }

輸出結果: false true (以上基於jdk8執行)

程式碼行8:先呼叫intern(),會在常量池建立物件並返回物件引用。

程式碼行9:s4宣告式顯示,在常量池中找到並返回物件。

因此,s3==s4是指向同一個物件。