美文网首页Java学习笔记Java 杂谈
Java源码分析-StringBuilder、StringBuf

Java源码分析-StringBuilder、StringBuf

作者: gatsby_dhn | 来源:发表于2016-10-06 08:07 被阅读263次

    String、StringBuilder、StringBuffer的区别老生常谈,最权威的莫过于源码。基于JDK1.8。

    支持原创,转载请注明出处。

    继承关系

    public final class StringBuilder
        extends AbstractStringBuilder
        implements java.io.Serializable, CharSequence
    
     public final class StringBuffer
        extends AbstractStringBuilder
        implements java.io.Serializable, CharSequence
    
    abstract class AbstractStringBuilder implements Appendable, CharSequence 
    

    StringBuilder、StringBuffer都继承自AbstractStringBuilder,因为这两个类的行为很像,将公共的行为提取到AbstractStringBuilder不失为一个好的选择。

    核心成员变量

    这两个类都将实现交给了父类AbstractStringBuilder,所以我们看下AbstractStringBuilder的成员变量:

    char[] value; 
    int count;
    

    很简单,就一个字符数组和成员计数。

    核心方法

    StringBuilder的append方法:

        @Override
        public StringBuilder append(String str) {
            super.append(str);
            return this;
        }
    
    

    StringBuffer的append方法:

        @Override
        public synchronized StringBuffer append(String str) {
            toStringCache = null;
            super.append(str);
            return this;
        }
    

    它们的区别在于StringBuffer的append方法是synchronized修饰,所以是线程安全的。我们看下AbstractStringBuilder的append方法:

        public AbstractStringBuilder append(String str) {
            if (str == null)
                return appendNull();
            int len = str.length();
            ensureCapacityInternal(count + len);//确保不会溢出,必要是扩容
            str.getChars(0, len, value, count);//将整个str拷贝到value的末尾
            count += len;            //增加计数
            return this;
        }
    
        private void ensureCapacityInternal(int minimumCapacity) {
            // overflow-conscious code
            if (minimumCapacity - value.length > 0)  //如果会溢出,则扩容
                expandCapacity(minimumCapacity);
        }
    
       void expandCapacity(int minimumCapacity) {
            int newCapacity = value.length * 2 + 2;   //新的容量是原容量的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);  
        }
    

    AbstractStringBuilder的append方法和ArrayList的add方法很像,先确保不会溢出,必要时进行扩容,然后将参数str复制到value的尾部。其他方法都类似,必要时翻看源码就可以啦。

    总结

    StringBuilder、StringBuffer的公共操作都在AbstractStringBuilder中,StringBuilder、StringBuffer的区别在于StringBuffer的方法被synchronized修饰,保证线程安全性的同时也损失了性能。

    支持原创,转载请注明出处。
    github:https://github.com/gatsbydhn

    相关文章

      网友评论

        本文标题:Java源码分析-StringBuilder、StringBuf

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