java基礎學習(2)-String相關知識

java基礎學習(1)-String相關知識

1.String、StringBuffer與StringBuilder的區別

  1. 可變性
    String不可變
    StringBuffer和StringBuilder可變
  2. 線程安全
    String不可變,因此爲線程安全
    StringBuilder是線程不安全的
    StringBuffer是線程安全的,內部使用synchronized同步

2.String不可變的好處

1.可以緩存hash值
因爲String的hash值經常被使用,例如String作爲HashMap的key。不變性可以使hash之不會發生變化,因此只需要進行一次計算。
2.String Pool的需要
如果一個String對象已經被創建了,那麼再次生成或者使用需要從String Pool中獲取引用。只有String是不可變的,纔可能是使用String Pool。
3.安全性
String經常作爲參數,String的不變性保證了參數的不可變。例如在作爲網絡連接參數的情況下如果String可變,那麼在網絡連接的過程中,String改變,改變String的那一方以爲現在連接的是其他主機,而實際情況卻不一定是。
4.線程安全
String 不可變性天生具備線程安全,可以在多個線程中安全地使用。

3.String底層數據結構變化

String 被聲明爲 final,因此它不可被繼承。
底層數組被聲明爲 final,這意味着 value 數組初始化之後就不能再引用其它數組。並且 String 內部沒有改變 value 數組的方法,因此可以保證 String 不可變。
在 Java 8 中,String 內部使用 char 數組存儲數據。
在 Java 9 之後,String 類的實現改用 byte 數組存儲字符串,同時使用 coder 來標識使用了哪種編碼。

4.String Pool

字符串常量池(String Pool)保存着所有字符串字面量(literal strings),這些字面量在編譯時期就確定。不僅如此,還可以使用 String 的 intern() 方法在運行過程將字符串添加到 String Pool 中。

當一個字符串調用 intern() 方法時,如果 String Pool 中已經存在一個字符串和該字符串值相等(使用 equals() 方法進行確定),那麼就會返回 String Pool 中字符串的引用;否則,就會在 String Pool 中添加一個新的字符串,並返回這個新字符串的引用。

下面示例中,s1 和 s2 採用 new String() 的方式新建了兩個不同字符串,而 s3 和 s4 是通過 s1.intern() 方法取得同一個字符串引用。intern() 首先把 s1 引用的字符串放到 String Pool 中,然後返回這個字符串引用。因此 s3 和 s4 引用的是同一個字符串。

String s1 = new String("aaa");
String s2 = new String("aaa");
System.out.println(s1 == s2);           // false
String s3 = s1.intern();
String s4 = s1.intern();
System.out.println(s3 == s4);           // true

如果是採用 “bbb” 這種字面量的形式創建字符串,會自動地將字符串放入 String Pool 中。

String s5 = "bbb";
String s6 = "bbb";
System.out.println(s5 == s6);  // true

在 Java 7 之前,String Pool 被放在運行時常量池中,它屬於永久代。而在 Java 7,String Pool 被移到堆中。這是因爲永久代的空間有限,在大量使用字符串的場景下會導致 OutOfMemoryError 錯誤。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章