Java源码分析-StringBuilder、StringBuffer

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、StringBuffer)