源码解读-StringBuffer

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。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值