【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),
    };
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章