JDK 源码解析 —— StringBuffer

首先来看看StringBuffer的定义

public final class StringBuffer  
    extends AbstractStringBuilder  
    implements java.io.Serializable, CharSequence {

    private transient char[] toStringCache;
    static final long serialVersionUID = 3388685877147921107L;

    public StringBuffer() {
        super(16);
    }

    public synchronized int length() {
        return count;
    }

定义成final形式,主要是为了“效率”和“安全性”的考虑.

其父类AbstractStringBuilder的定义如下:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
 /**
  * 存储字符串的字符数组,非final类型,区别于String类
  */
 char[] value;
 
 /**
  * The count is the number of characters used.
  */
 int count;
 
 public AbstractStringBuilder append(String str) {
  if (str == null)
   return appendNull();
  int len = str.length();
   //检查是否需要扩容
  ensureCapacityInternal(count + len);
  //字符串str拷贝至value  
  str.getChars(0, len, value, count);
  count += len;
  return this;
}
 
 private void ensureCapacityInternal(int minimumCapacity) {
  // overflow-conscious code
  // minimumCapacity=count+str.length
  //拼接上str后的容量 如果 大于value容量,则扩容
  if (minimumCapacity - value.length > 0) {
     
    //扩容,并将当前value值拷贝至扩容后的字符数组,返回新数组引用
   value = Arrays.copyOf(value,
     newCapacity(minimumCapacity));
  }
 }
 
 //StringBuilder扩容
 private int newCapacity(int minCapacity) {
  // overflow-conscious code
  // 计算扩容容量
  // 默认扩容后的数组长度是按原数(value[])组长度的2倍再加上2的规则来扩展,为什么加2?
  int newCapacity = (value.length << 1) + 2;
  if (newCapacity - minCapacity < 0) {
   newCapacity = minCapacity;
  }
  return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
   ? hugeCapacity(minCapacity)
   : newCapacity;
 }
}

StringBuffer和StringBuilder用一样,内部维护的value[]字符数组都是可变的,区别只是StringBuffer是线程安全的,它对所有方法都做了同步,StringBuilder是线程非安全的,因此在多线程操作共享字符串变量的情况下字符串拼接处理首选用StringBuffer, 否则可以使用StringBuilder,毕竟线程同步也会带来一定的消耗。

你可能感兴趣的:(JDK 源码解析 —— StringBuffer)