1.public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence
StringBuffer继承了AbstractStringBuilder,与Serializable,CharSequence,而AbstractStringBuilder继承了Appandable接口,与CharSquence接口,所以对比String他就多继承了一个Appandable接口而已。
2.private transient char[] toStringCache;
一个不可被序列化属性,buffer的缓存。
3.public StringBuffer() { super(16); }
4.public StringBuffer(int capacity) { super(capacity); }
5.public StringBuffer(String str) { super(str.length() + 16); append(str); }
6.public StringBuffer(CharSequence seq) { this(seq.length() + 16); append(seq); }
super:
AbstractStringBuilder(int capacity) { value = new char[capacity]; }
构造方法,为AbstractStringBuilder的构造方法,像hashMap一样,初始化的时候就给与16个char大小的char数组这点与String有比较大的区别。如果初始化的时候有一个String,那么还需要将他的大小增加16,append方法稍显复杂,所有的append会经过capacity的计算,如果capacity不够就扩容,在AbstractStringBuilder中看到扩容的方式是value.length*2+2,如果有入参minCapacity的话就至少要大于minCapacity。ensureCapacityInternal()这个AbstractStringBuilder方法会在append的时候去确认数组的大小够大。
7.public synchronized int length() { return count; }
8.public synchronized int capacity() { return value.length; }
可以发现这两个synchronized方法是要返回数组大小的, 一个是返回数组已经用了多少的字符(count),另一个是数组大小(capacity)
9.public synchronized void trimToSize() { super.trimToSize(); }
将char数组的大小调到最小
10.public synchronized void setLength(int newLength) { toStringCache = null; super.setLength(newLength); }
super:
public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength); ensureCapacityInternal(newLength); if (count < newLength) { Arrays.fill(value, count, newLength, '\0'); } count = newLength; }
方法是设置buffer的长度,所以,先扩容,因为buffer.length返回的是count,所以要把count撑到最大,那原本没有值的就用空格撑大。
11.(AbstartStringBuilder)public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { if (srcBegin < 0) throw new StringIndexOutOfBoundsException(srcBegin); if ((srcEnd < 0) || (srcEnd > count)) throw new StringIndexOutOfBoundsException(srcEnd); if (srcBegin > srcEnd) throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); }
12.public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; }
13.public synchronized StringBuffer append(CharSequence s) { toStringCache = null; super.append(s); return this; }
这几个方法都有很多重载方法,只是拿其中一个来举例,在StringBuffer的synchronized Append方法中,其实是调用父类AbstractStringBuilder的append方法,然后经过ensureCapacityInternal计算StringBuffer的capacity数组大小之后,调用getChars方法,使用System.arrayCopy的方法来append,在每次改动StringBuffer的实际内容的时候都要清楚toStringCache的内容,不然toString会出错(为什么要缓存起来?读写较快?),如果是调用delete方法删减StringBuffer的长度的话不会重新计算capacity。