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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,767评论 18 399
  • 相关概念 面向对象的三个特征 封装,继承,多态.这个应该是人人皆知.有时候也会加上抽象. 多态的好处 允许不同类对...
    东经315度阅读 1,992评论 0 8
  • 当你和别人都能实现一个某个功能,这时候区分你们能力的不是谁干活多少,而是谁能写出效率更高的代码。比如显示一个订单列...
    凤之恋阅读 7,594评论 4 93
  • 现在的社会,自由恋爱已经成为男女主流的择偶方式。两个人从相识、相知、相恋、相爱,最后进入了他们人生第一次的身体接触...
    我爱微播阅读 717评论 0 0
  • 有人说人生就像列车有上车有下车的,有遇见的有再见的,有看到的有过往的,不管如何你将都要失去! 在我看来人生...
    李高杰阅读 538评论 1 1