[JDK1.8 source code reading] StringBuffer and StringBuilder comparison (end)

Object performance String StringBuffer (thread safe) StringBuilder (non-thread safe)
Performance ratio 50000 5 4
inherit no AbstractStringBuilder AbstractStringBuilder (will throw an error)

Variable difference

private transient char[] toStringCache;

StringBuffer has the variable toStringCache, and its qualifier transient table is not serialized.

Method differences

StringBuffer has one more synchronized than StringBuilder, see the principle of synchronized for details.

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;
    }

The toString method of StringBuffer is slightly different from the toString method of StringBuilder. Here is a String object constructed by the toStringCache member and then returned. Because the String object created here calls the String (char [] value, boolean share) constructor of the String class, which is a shared character array, to improve efficiency. Students who are not clear can see the previous String source code. So the designer uses toStringCache to ensure that the String object obtained every time the toString method is called is unchanged. Imagine if you did not use toStringCache, but directly shared the value, then after calling toString method, and then operate on StringBuffer, the String object returned before changed, which violated the unchanged design concept of String object.
For the other methods are implemented by calling the method of the parent class, but all have added synchronized to ensure the effect of thread safety. Here is a function example. For other methods, see the implementation of its parent class AbstractStringBuilder. (Extract: 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);
    }

Save the state of the StringBuilder object to a stream during serialization ( putting the memory object into a file ). See java.io.ObjectOutputStream for details. The difference and the scene are not clear .

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万+

Guess you like

Origin blog.csdn.net/lglglgl/article/details/105040254