Java·String、StringBuilder、StringBuffer

1.String

String類的基本字段(field)

Java9之后,String中用byte[]存儲字符串,并用coder表示該字符串使用哪種編碼。
coder主要是為了適應不同語言字符的需要,有的字符需要2字節編碼,有的只需要1字節,coder就表示這個字符串應當使用哪種編碼規則。這樣在存儲像英文一樣只需要一個字節的字符時,可以壓縮空間。coder有LATIN1(1字節)和UTF16(2字節)兩種選項,相關的還有COMPACT_STRINGS,為true表示這個字符串是壓縮的。編碼這塊由JVM處理。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final byte[] value;

    /** The identifier of the encoding used to encode the bytes in {@code value}. */
    private final byte coder;

    static final boolean COMPACT_STRINGS;
    static {
        COMPACT_STRINGS = true;
    }

    /** Cache the hash code for the string */
    private int hash; // Default to 0
}

不可變的String

String類是final的,存儲的byte[]也是final的,所以保證String不可變。
不可變的好處

  1. 可以緩存hash值
  2. String Pool 的需要
  3. 幫助其他Objects的使用
    • 例如Set<String>中,如果String可變,改變后的String可能違反set規則
  4. 安全性
    • 例如在作為網絡連接參數時,保證String不可變更具安全性
  5. 線程安全

Program Creek : Why String is immutable in Java?

構造函數

在將一個字符串對象作為另一個字符串對象的構造函數參數時,并不會完全復制 value 數組內容,而是都會指向同一個 value 數組

public String(String original) {
    this.value = original.value;
    this.hash = original.hash;
}

Java基礎-String

2. StringBuilder和StringBuffer

和String一樣用byte[]存儲,也有coder成員。但是這兩個都是可變的,類內部提供append()之類的修改字符串的方法。
二者都繼承自AbstractStringBuilder,其實相差不大,主要是StringBuffer中很多方法都被關鍵字synchronized修飾,因此StringBuffer是線程安全的,而StringBuilder是線程不安全的。也因此,但單線程的情況下, StringBuilder的性能要比StringBuffer更好。
如果要對一個字符串做頻繁修改,最好用StringBuilder,如果是在多線程的情況下(變量可能被多個線程訪問),最好用StringBuffer。

Java 之 synchronized 詳解
深入理解Java并發之synchronized實現原理

3. StringPool 字符串常量池

String Pool保存著所有字符串字面量(literal strings),這些字面量在編譯時期就確定。可以使用 String 的 intern() 方法在運行過程中將字符串添加到 String Pool 中。
intern()
當一個字符串調用 intern() 方法時,如果 String Pool 中已經存在一個字符串和該字符串值相等(使用 equals() 方法進行確定),那么就會返回 String Pool 中字符串的引用;否則,就會在 String Pool 中添加一個新的字符串,并返回這個新字符串的引用。

String s1 = "hello";  //用字面量創建字符串,會自動將字符串放入 String Pool 中
String s2 = s1.intern(); //返回的是常量池中"Hello"字符串的引用

String Pool是一個固定大小的Hashtable,默認值大小長度是1009,如果放進String Pool的String非常多,就會造成Hash沖突嚴重,從而導致鏈表會很長,而鏈表長了后直接會造成的影響就是當調用 String.intern() 時性能會大幅下降。在jdk7中,StringTable的長度可以通過一個參數指定:XX:StringTableSize=99991

深入解析 String#intern

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 從網上復制的,看別人的比較全面,自己搬過來,方便以后查找。原鏈接:https://www.cnblogs.com/...
    lxtyp閱讀 1,358評論 0 9
  • 前言 最先接觸編程的知識是在大學里面,大學里面學了一些基礎的知識,c語言,java語言,單片機的匯編語言等;大學畢...
    oceanfive閱讀 3,129評論 0 7
  • 字符串(String)廣泛應用于 Java 編程中,在 Java 中字符串不屬于基礎類型,屬于對象,Java 提供...
    Alex90閱讀 861評論 0 0
  • 四怪逃走后不久,重明隱隱約約地看到一白衫女子從天上緩緩飄落。 那女子翩然而至,廣袖飄飄,風姿卓然,宛然如生...
    鯉魚胤潛閱讀 446評論 0 1
  • 黑暗里走過的還是黑暗 記憶力流出的是曾經的美好 枕頭不安得在磨蹭著耳朵 記憶的被角只有自己蓋上 無數的窗外 哪一個...
    大榕樹上閱讀 285評論 0 0