java stringbuffer原理_String,StringBuilder,StringBuffer 实现原理解析
定義:
從jdk1.5開始提供的新的封裝字符串的類,StringBuilder,其字符串拼接操作的效率遠遠高于 String。
Java里面提供了String,StringBuffer和StringBuilder三個類來封裝字符串
簡介:
我們知道字符串其實就是由若干個字符線性排列而成的,可以理解為字符數組Array,那么既然是數組實現的,那就需要考慮到數組的特性,數組在內存中是一塊連續的地址空間塊,即在定義數組的時候需要指定數組的大小
換言之, 數組就分為可變數組和不可變數組。可變數組能夠動態插入和刪除,而不可變數組一旦分配好空間后則不能進行動態插入或刪除操作。
在實際的字符串應用場景中,涉及到多種操作,比如字符串的插入,刪除,修改,拼接,查詢,替換...
String:
不可變類,屬性value為不可變數組,即String初始化構造器沒有初始容量為16的概念,你定義多少,String中字符數組的長度就是多少,不存在字符數組擴容一說。看下源碼:
2
3
final修飾的String 類,以及final修飾的char[] value,表示String類不可被繼承,且value只能被初始化一次。這里的value變量其實就是存儲了String字符串中的所有字符。
那既然String,不可變。我們再看下它的截取方法subString()實現
4
這里可以看到,在substring方法中,如果傳入的參數為0,就返回自身原對象,否則就是重新創建一個新的對象。
5
6
類似的我們可以看到,String類的concat方法,replace方法,都是內部重新生成一個String對象的。
這也就是為什么我們如果采用String對象頻繁的進行拼接,截取,替換操作效率很低下的原因。
下面再看下StringBuilder對象的源碼,分析為何其在做字符串的拼接,截取,替換方面效率遠遠高于String
StringBuilder:
內部可變數組,存在初始化StringBuilder對象中字符數組容量為16,存在擴容。
7
StringBuilder類繼承AbstractStringBuilder抽象類,其中StringBuilder的大部分方法都是直接調用的父類的實現。
首先看下StringBuilder的構造方法
8
1:空參數的構造方法
9
10
2:自定義初始容量-構造函數
11
3:以字符串String 作為參數的構造
12
在參數Str 數組長度的基礎上再增加16個字符長度,作為StringBuilder實例的初始數組容量,并將str字符串 append到StringBuilder的數組中。
13
具體看下父類AbstractStringBuilder的append方法
14
1:首先判斷append的參數是否為null,如果為null的話,這里也是可以append進去的
15
其中ensureCapacityInternal方法是確保這次append 的時候StringBuilder的內部數組容量是滿足的,即這次要append的null字符長度為4,加上之前內部數組中已有的字符位數c之后作為參數執行。
16
2:如果不為null的話,就獲取這次需要append的str的字符長度。緊接著執行是否需要擴容的方法
3:重點看下append方法的關鍵:String的 getChars方法(從str的0位開始,到str的長度,當前StringBuilder對象的字符數組,當前數組已有的字符長度)
17
18
其實是調用了System的arraycopy方法 參數如下:
value為str的內部不可變字符數組,
srcBegin為從str 字符串數組的0下標開始,
srcEnd為str字符串數組的長度,
dst為StringBuilder對象的內部可變字符數組,
dstBegin則為StringBuilder對象中已有的字符長度(char[] 已有的元素長度)
即整個StringBuilder的append方法,本質上是調用System的native方法,直接將String 類型的str字符串中的字符數組,拷貝到了StringBuilder的字符數組中
19
toString():
最后說下StringBuilder的toString方法,
這里的toString方法直接new 一個String對象,將StringBuilder對象的value進行一個拷貝,重新生成一個對象,不共享之前StringBuilder的char[]
以上就是StringBuilder的拼接字符串的原理分析,可以發現沒有像String一樣去重新new 對象,所以在頻繁的拼接字符上,StringBuilder的效率遠遠高于String類。
StringBuffer:
線程安全的高效字符串操作類,看下源碼:
19
類圖和StringBuilder一樣,不多說
構造函數:
20
和StringBuilder一樣,也不用多說,重點看下其append方法:
21
可以看到這里就是在append方法上加了同步鎖,來實現多線程下的線程安全。其他的和StringBuilder一致。
這里比StringBuilder多了一個參數
22
這里的作用簡單介紹一下,就是去緩存toString的
可以看下StringBuffer的toString方法
23
這里的作用就是如果StringBuffer對象此時存在toStringCache,在多次調用其toString方法時,其new出來的String對象是會共享同一個char[] 內存的,達到共享的目的。但是StringBuffer只要做了修改,其toStringCache屬性值都會置null處理。這也是StringBuffer和StringBuilder的一個區別點。
總結:
String 類不可變,內部維護的char[] 數組長度不可變,為final修飾,String類也是final修飾,不存在擴容。字符串拼接,截取,都會生成一個新的對象。頻繁操作字符串效率低下,因為每次都會生成新的對象。
StringBuilder 類內部維護可變長度char[] , 初始化數組容量為16,存在擴容, 其append拼接字符串方法內部調用System的native方法,進行數組的拷貝,不會重新生成新的StringBuilder對象。非線程安全的字符串操作類, 其每次調用 toString方法而重新生成的String對象,不會共享StringBuilder對象內部的char[],會進行一次char[]的copy操作。
StringBuffer 類內部維護可變長度char[], 基本上與StringBuilder一致,但其為線程安全的字符串操作類,大部分方法都采用了Synchronized關鍵字修改,以此來實現在多線程下的操作字符串的安全性。其toString方法而重新生成的String對象,會共享StringBuffer對象中的toStringCache屬性(char[]),但是每次的StringBuffer對象修改,都會置null該屬性值。
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的java stringbuffer原理_String,StringBuilder,StringBuffer 实现原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java异常 子类_Java异常 Exc
- 下一篇: java 一般方法_一般覆盖Java中的