StringBuffer類繼承自AbstractStringBuilder抽象類,實作Serializable序列化接口和CharSequence接口。
AbstractStringBuilder抽象類實作Appendabel,CharSequence接口。
另外,StringBuilder的源碼跟StringBuffer類似,看完Buffer再看Builder,找出不同點看看就大緻可以。
一,關于append方法淺析。
append方法都做了同步聲明,其中源碼如下
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
1、StringBuffer的方法都加了synchronized關鍵字,線程安全。
2、synchronized代表方法加鎖,例如線程A,要運作到聲明了synchronized 方法時,先檢查有沒有其他線程B,C正在使用這synchronized 方法,若有就先等B,C線程運作完這個synchronized 方法後,在運作A,若無直接運作,
3、synchronized兩種用法:synchronized方法和synchronized塊。
synchronized(syncObject) { // synchronized代碼塊
//允許通路控制的代碼
}
4、圍觀append源碼
第一步:StringBuffer類體内
/*
* 可見是通過super調用父類AbstractStringBuilder中定義的append方法。
*/
public synchronized StringBuffer append(StringBuffer sb) {
super.append(sb);
return this;
}
第二步:AbstractStringBuilder抽象類體内
/**
* AbstractStringBuilder屬性有:
* char value[]; // The value is used for character storage(). 容量
* int count; // The count is the number of characters used.實際字元數
*/
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return append("null");
int len = sb.length();
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount); // 若value存儲容量不夠需擴容。擴容方法省略暫不分析,基本上根據Arrays.copyOf()方法,複制指定的數組,以使副本具有指定的長度。到頭來copyOf的源碼一樣是利用arraycopy方法來複制數組和擴容
sb.getChars(0, len, value, count); // 把sb的内容0->len複制到value中,注意value參數,此時的value是已經擴容後的value。
count = newCount; // 更新新count值
return this;
}
原有count要加上len(len也就是新增的count)成newCount,若這newCount總數要大于原有value的容量,就要 擴容才可以容納newCount個字元。再用getChars複制數組。
第三步:AbstractStringBuilder裡定義的getChars方法體,是對System.arraycopy方法 + 邊界檢查的進一步封裝 而已。
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) // dstBegin就是原有count接下來的位置
{
if (srcBegin < 0)
throw new StringIndexOutOfBoundsException(srcBegin);
if ((srcEnd < 0) || (srcEnd > count))
throw new StringIndexOutOfBoundsException(srcEnd);
if (srcBegin > srcEnd)
throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); //以上是Bound Check
System.arraycopy(value, srcBegin,dst, dstBegin, srcEnd - srcBegin); // 從指定源數組中複制一個數組
}
arraycopy方法參數
src
- 源數組。
srcPos
- 源數組中的起始位置。
dest
- 目标數組。
destPos
- 目标資料中的起始位置。
length
- 要複制的數組元素的數量。
注意value和dst
這個value是sb.value,srcEnd-srcBegin個元素全部複制dst(也就是擴容的value)中。(這裡我了解正确嗎?)
待續...