當前位置:
首頁 > 最新 > 從JDK源碼看StringBuffer

從JDK源碼看StringBuffer

概況

Java 中處理字元串時經常使用的 String 是一個常量,一旦創建後不能被改變。為了提供可修改的操作,引入了 StringBuilder 類,可看前面的文章《從JDK源碼看StringBuilder》。但它不是線程安全的,只用在單線程場景下。所以引入了線程安全的 StringBuffer 類,用於多線程場景。

總的來說主要是通過在必要的方法上加 synchronized 來實現線程安全。

三種字元串類關係


這裡寫圖片描述

繼承結構

類定義

StringBuffer 類被聲明為 final,說明它不能再被繼承。同時它繼承了 AbstractStringBuilder 類,並實現了 Serializable 和 CharSequence 兩個介面。

其中 Serializable 介面表明其可以序列化。

CharSequence 介面用來實現獲取字元序列的相關信息,介面定義如下:

獲取字元序列長度。

獲取某個索引對應字元。

獲取指定範圍子字元串。

轉成字元串對象。

用於獲取字元序列的字元的 int 類型值的流,該介面提供了默認的實現。

用於獲取字元序列的代碼點的 int 類型的值的流,提供了默認的實現。

主要屬性

toStringCache 用於緩存調用方法生成的 String 對象,避免每次都要根據編碼生成 String 對象。

value 該數組用於存儲字元串值。

coder 表示該字元串對象所用的編碼器。

count 表示該字元串對象中已使用的字元數。

構造方法

有若干種構造方法,可以指定容量大小參數,如果沒有指定則構造方法默認創建容量為16的字元串對象。如果 COMPACT_STRINGS 為 true,即使用緊湊布局則使用 LATIN1 編碼(ISO-8859-1編碼),則開闢長度為16的 byte 數組。而如果是 UTF16 編碼則開闢長度為32的 byte 數組。

如果構造函數傳入的參數為 String 類型,則會開闢長度為的 byte 數組,並通過方法將字元串對象添加到 byte 數組中。

類似地,傳入參數為 CharSequence 類型時也做相同處理。

主要方法

為了實現線程安全,其實最簡單也可能是最沒效率的方法就是通過對某些方法進行同步,以此允許並發操作。所以 StringBuffer 和 StringBuilder 其實實現邏輯幾乎都一樣,並且抽象到 AbstractStringBuilder 抽象類中來實現,只是 StringBuffer 將一些必要的方法進行同步處理了。

StringBuffer 中大多數方法都只是加了 synchronized。

比如下面該方法加了同步來保證計數的準確性。此外還包含很多其他方法,比如、、、、、、、、、、、、。


該方法用於將該 StringBuffer 對象的容量壓縮到與字元串長度大小相等。重寫了該方法,主要是添加了同步,保證了數組複製過程的準確性。


有多個方法,都只是傳入的參數不同而已,同樣是使用了 synchronized,另外它還會清理緩存 toStringCache,這是因為 append 後的字元串的值已經變了,所以需要重置緩存。重置緩存的方法還包括:、、、、、。


使用同步操作,先判斷緩存是否為空,如果為空則先根據編碼(Latin1 或 UTF16)創建對應編碼佔位的 String 對象,然後創建新 String 對象並返回。


該方法是序列化方法,分別將 value、count、shared 欄位的值寫入。


該方法是反序列方法,分別讀取 value 和 count,並且初始化對象內的位元組數組和編碼標識。

--------------------------------------

跟我交流,向我提問:


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 遠洋號 的精彩文章:

卷積神經網路文本分類
深入談談String.intern在JVM的實現

TAG:遠洋號 |