【JDK1.8源码阅读】StringBuffer与StringBuilder对比(完)

对象性能 String StringBuffer(线程安全) StringBuilder(非线程安全)
性能比例 50000 5 4
继承 AbstractStringBuilder AbstractStringBuilder(会抛错误)

变量差异

private transient char[] toStringCache;

StringBuffer拥有变量toStringCache,其限定词transient表不做序列化。

方法差异

StringBuffer比StringBuilder多一个synchronized,详见synchronized原理。

StringBuffer append(String str)

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

StringBuilder append(String str)

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

StringBuffer reverse()

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

StringBuilder reverse()

 @Override
    public StringBuilder reverse() {
        super.reverse();
        return this;
    }

StringBuffer的toString方法与StringBuilder的toString方法有一点区别。这里是通过toStringCache成员构造String对象然后返回的。因为这里创建String对象调用的是String类的String(char[] value, boolean share)构造方法,是共享字符数组的,以提高效率不清楚的同学可以看下之前的String源码。所以设计者通过toStringCache来保证每次调用toString方法时得到的String对象是不变所结果。试想一下如果没有使用toStringCache,而是直接共享了value,那么在调用toString方法后,再对StringBuffer进行操作的时候之前返回的String对象就改变了,违背了String对象不变的设计理念。
对于其它的方法都是调用父类的方法实现,但都加上了synchronized来保证线程安全的效果。这里拿一个函数举例说明。其它的方法实现看其父类AbstractStringBuilder实现.(摘:https://www.jianshu.com/p/6a713cad80a9)

StringBuffer toString()

 @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

StringBuilder toString()

 @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

在进行序列化(将内存的对象放到文件里)的时候保存StringBuilder对象的状态到一个流中。详见java.io.ObjectOutputStream。二者差异及场景未明

StringBuffer writeObject(java.io.ObjectOutputStream s)

private synchronized void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        java.io.ObjectOutputStream.PutField fields = s.putFields();
        fields.put("value", value);
        fields.put("count", count);
        fields.put("shared", false);
        s.writeFields();
    }

StringBuilder writeObject(java.io.ObjectOutputStream s)

private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        s.defaultWriteObject();
        s.writeInt(count);
        s.writeObject(value);
    }

StringBuffer serialPersistentFields

 private static final java.io.ObjectStreamField[] serialPersistentFields =
    {
        new java.io.ObjectStreamField("value", char[].class),
        new java.io.ObjectStreamField("count", Integer.TYPE),
        new java.io.ObjectStreamField("shared", Boolean.TYPE),
    };
发布了99 篇原创文章 · 获赞 106 · 访问量 27万+

猜你喜欢

转载自blog.csdn.net/lglglgl/article/details/105040254