簡單瞭解StringBuffer內部情況
阿新 • • 發佈:2020-06-24
此時此刻,突然對
StringBuffer
產生了些許'興趣',本著給大家分享些基礎知識,同時鞏固下自己的基礎知識的美好意願,給大家寫了這篇帖子(其實就是閒的哈哈哈)。好了廢話不多說,進入正題。
正題
像String
,StringBuffer
,StringBuilder
這三個的基本介紹就不多說了,相信大家都清楚,不清楚的可以前往某歌或某度查詢(●'◡'●)。
我們先來看下StringBuffer內部的一個大概情況:
可以看到我們的StringBuffer
繼承了AbstractStringBuilder
類,實現了Serializable
介面和CharSequence
介面,並且裡面的方法都加了Synchronized
StringBuffer
是執行緒安全的。
但是我們儲存的字串資料並不是在自己的類中,而是用他的父類AbstractStringBuilder
中一個char型別的字元陣列用來儲存,count就是用來記錄實際字元數的,後面也會講到。
我們在看下他初始化方法,這裡只列舉了一部分,通過這些構造方法看出,都是呼叫父類的構造方法給父類的char型別陣列賦值,並且預設不帶引數的長度為16,如果帶引數的話,就為引數長度加上16。
這有個需要注意的點,就是如果我們通過無參構造建立一個空的StringBuffer
的變的話,輸出他的長度是0而不是16,這就和他父類的count屬性有關了。官方註釋寫到這是count是記錄字元數,也就是實際有多少個元素。看下StringBuffer
length()
方法,並不是直接返回value.length()
的,而是返回count的值。
那就有人問了(其實沒人想問),那的字元陣列滿了怎麼辦?我們自己看他底層的擴容方法,那要擴容的話肯定是在往裡面加的時候做的,這時候我們直接看到append()
方法,他裡面有很多過載的方法,這裡我們就拿引數型別為String
的舉例:
可以看到,最終還是呼叫的父類的方法:
進入方法,先判斷是否為空,然後獲取我們新增的字串長度,在呼叫ensureCapacityInternal()
方法,把我們的要新增的字串長度和原字元陣列實際個數相加做為形參新增進去,我們可以看下這個方法:先會判斷是否需要擴容,然後進行下一步操作newCapacity()
方法:
這裡,我們就很清楚的看到了StringBuffer
的擴容是在原來的繼承上擴容1倍在加上2,然後返回新的長度,最終通過Arrays.copyOf()
完成擴容。回到append()
方法可以看到,在最後的時候對count的值進行了增加,而這個值也是字元陣列中實際數量的值。
但在實際開發的時候我還是推薦大家儘量少進行擴容操作,因為每次擴容都需要進行復制,對效率會有所影響。所以推薦大家在建立StringBuffer
的時候就使用構造器對長度進行初始化。
好了,以上就是這次帶大家簡單瞭解了下StringBuffer
的一些內部情況,我們下篇再見哦!