走近Java之幕後的String

前幾天,有個同事問了我一個表面看起來顯而易見的問題,是關於String的,咱們一塊兒來看一下(若是有說的不正確的地方,歡迎你們指正)。java

image

java中,字面量在編譯期計算,而且String字面量做爲常量,存儲在方法區中,僅保留一份。帶有變量的計算,在運行期執行。那麼,str3在執行的時候,發生了什麼。數組

第一步,初始化一個StringBuilder對象,並在構造器中調用父類AbstractStringBuilder的構造器,初始化一個長度16的字符數組app

image

image

第二步,調用StringBuilder的append()方法,傳入變量str1,內部調用父類AbstractStringBuilder的append()方法性能

image

image

在入參不爲null的狀況下,先調用ensureCapacityInternal()方法,判斷拼接後的字符串長度是否超過當前字符數組的長度。若是超過了,就計算一個新的長度,而後建立一個新的數組,將現有數組的值複製給它,ui

image

具體擴容規則是,將當前字符數組長度擴容一倍再加2,若是擴容後的數組長度還不夠,就和Integer.MAX_VALUE - 8(即MAX_ARRAY_SIZE)比較,若是還不夠,則就用拼接後的字符串長度,可是最大也不能超過Integer.MAX_VALUE。(有一個newCapacity <= 0的判斷,是考慮到value.length << 1變負數;至於擴容一倍還要+2,我的覺得是爲了提升性能,廣泛計算得出,若是有不一樣理解,歡迎你們評論)3d

image

image

第三步,調用str.getChars()方法,將入參字符串拼接到現有的字符數組後面,實際操做是調用本地方法對象

System.arraycopy()。
image

第四步,記錄下字符個數,最後返回當前StringBuilder對象。blog

第五步,拼接字符串」bbb」,重複第二步到第四步,ci

最後,調用StringBuilder的toString方法,去掉多餘的空字符,返回一個當前累計字符長度的String對象,字符串

其實也是調用本地方法System.arraycopy()。複製一個新的字符數組。正好符合String的不變類特性。

image

image

image

相關文章
相關標籤/搜索