Java源码阅读之StringBuffer

Summary:

  • 只是导入了import java.util.Arrays;
  • public final class StringBuffer  extends AbstractStringBuilder;父类是一个StringBuidler的抽象类
  • String Buffer中的很多方法使用了关键字Synchronized,所以是线程安全的
  • 与String的区别就是字符数组不是声明为final;中间的对于字符的修改除了setCharAt方法没有使用System.arraycopy方法外,其它方法都是调用了这个方法进行实现的;
  • 可以通过trimToSize()方法进行减容,Capacity减到当前存有的数据大小

Fields:

private transient char[] toStringCache;
//toStringCache的作用是缓存上次返回String对应的char数组的引用,详参toString方法
父类有两个域:
  char[] value; //数据的引用
  int count; //记录当前存储的数据长度,小于等于value.length

Constructor:

//参考AbstractStringBuilder可以知道是创建一个长度为16的字符数组
public StringBuffer() {
        super(16);
}
//参考AbstractStringBuilder可以知道是创建一个长度为str.length()+16的字符数组
public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
}

length():

//返回当前存储的字符数
@Override
public synchronized int length() {
        return count;
}

charAt():

//等同于数组的随机访问操作;
@Override
public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
}

getChars():

//父类最终是调用System.arraycopy方法,从父类的value中取出目标中的字符存入到目标字符数组中
@Override
public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
{
        super.getChars(srcBegin, srcEnd, dst, dstBegin);
}

capacity():

//返回能当前容器的容量大小;
@Override
public synchronized int capacity() {
        return value.length;
}

append():

//调用父类中append方法;
@Override
public synchronized StringBuffer append(XX str) {
        toStringCache = null;
        super.append(str);
        return this;
}
//以下是父类AbstractStringBuilder的append方法
//将XX中的字符复制到value数组中,同时更新count值
public AbstractStringBuilder append(XX str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);//确保当前的value容量足够的大!
        str.getChars(0, len, value, count); //String的getChars方法
        count += len;
        return this;
}
//以下是父类AbstractStringBuilder的ensureCapacityInternal方法
//如果当前容量小于需求容量则扩容
private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0)
            expandCapacity(minimumCapacity);
}
//以下是父类AbstractStringBuilder的expandCapacity方法
//首先扩容两倍,如果扩容后还是小于当前要求最小容量则扩容容量到当前要求最小容量
//最后判断如果容量大于Integer.MAX_VALUE;则赋值Integer.MAX_VALUE
//最后将当前的value值赋值到新的char数组中;
void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
}

减容

public void trimToSize() {
        if (count < value.length) {
            value = Arrays.copyOf(value, count);
        }
}

insert();

//调用父类的insert方法
@Override
public synchronized StringBuffer insert(int offset, String str) {
        toStringCache = null;
        super.insert(offset, str);
        return this;
}
//首先将offset到count的数据往后移动str.length()长度
//随后调用string的getChars方法将str中的数据存入value中
public AbstractStringBuilder insert(int offset, String str) {
        if ((offset < 0) || (offset > length()))
            throw new StringIndexOutOfBoundsException(offset);
        if (str == null)
            str = "null";
        int len = str.length();
        ensureCapacityInternal(count + len);
        System.arraycopy(value, offset, value, offset + len, count - offset);
        str.getChars(value, offset);
        count += len;
        return this;
}

setCharAt():

//修改父类中value域的值,String类中不能进行该操作!注意此处没有使用synchronized
public void setCharAt(int index, char ch) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        value[index] = ch;
}

delete():

@Override
    public synchronized StringBuffer delete(int start, int end) {
        toStringCache = null;
        super.delete(start, end);
        return this;
}
//以下是父类AbstractStringBuilder的 delete方法
//将value在end后面的数据移动到start前面来
public AbstractStringBuilder delete(int start, int end) {
        if (start < 0)
            throw new StringIndexOutOfBoundsException(start);
        if (end > count)
            end = count;
        if (start > end)
            throw new StringIndexOutOfBoundsException();
        int len = end - start;
        if (len > 0) {
            System.arraycopy(value, start+len, value, start, count-end);
            count -= len;
        }
        return this;
    }
//java.lang.System.arraycopy方法声明为public static native void arraycopy( Object src,  int  srcPos, Object dest, int destPos, int length);

deleteCharAt();

//其底层实现方式跟delete()方法一样都是调用System.arraycopy
public AbstractStringBuilder deleteCharAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        System.arraycopy(value, index+1, value, index, count-index-1);
        count--;
        return this;
}

toString();

@Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
}





你可能感兴趣的:(Java源码)