美文网首页
JDK 源码解析 —— StringBuffer

JDK 源码解析 —— StringBuffer

作者: 01_小小鱼_01 | 来源:发表于2018-05-27 00:28 被阅读9次

    首先来看看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

          本文链接:https://www.haomeiwen.com/subject/uqbvjftx.html