JDK源码解析 - java.lang.StringBuffer

1.实现接口

/**
 * Whenever an operation occurs involving a source sequence (such as
 * appending or inserting from a source sequence), this class synchronizes
 * only on the string buffer performing the operation, not on the source.
 * Note that while {@code StringBuffer} is designed to be safe to use
 * concurrently from multiple threads, if the constructor or the
 * {@code append} or {@code insert} operation is passed a source sequence
 * that is shared across threads, the calling code must ensure
 * that the operation has a consistent and unchanging view of the source
 * sequence for the duration of the operation.         
 *  //只对append或insert的字符缓冲区线程安全,对源字符不保证
 */
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{
	...
	static final long serialVersionUID = 3388685877147921107L;
    // Serializable fields for StringBuffer. Stringbuffer特有序列化
    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),
    };

    /**
     * readObject is called to restore the state of the StringBuffer from
     * a stream. 
     */
    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();
    }

    /**
     * readObject is called to restore the state of the StringBuffer from
     * a stream.
     */
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        java.io.ObjectInputStream.GetField fields = s.readFields();
        value = (char[])fields.get("value", null);
        count = fields.get("count", 0);
    }
}

2.toStringCache

    /**
     * A cache of the last value returned by toString. Cleared
     * whenever the StringBuffer is modified.
     */
    private transient char[] toStringCache;
    
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
  • 缓存数组,每次对Stringbuffer修改都会将该数组清空,而toString方法会将当前数组value中值赋给该数组toStringCache,返回一个新String对象
  • transient 关键字修饰的变量在序列化的时候不会被保存到文件中,也就是通过序列化后再被反序列化后读取这个变量不会有值。被static修饰的变量应该也是不会被序列化的,因为只有堆内存会被序列化.所以静态变量会天生不会被序列化。那这里被static修饰的变量反序列化后有值又是什么鬼 ,这是因为静态变量在方法区,本来流里面就没有写入静态变量,我们打印静态变量当然会去方法区查找,我们当前 jvm 中有所以静态变量在序列化后任然有值。

3.构造方法

    public StringBuffer() {
        super(16);
    }
    
    public StringBuffer(int capacity) {
        super(capacity);
    }
    
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }
   
    public StringBuffer(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

16这个数字记住就完事了

3.其他方法(都用synchronized修饰)

    @Override
    public synchronized int length() {
        return count;
    }
    
    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }
    ....

先toStringCache清空,在调用父类AbstractStringBuilder中的方法

参考资料:
https://blog.csdn.net/weixin_30484247/article/details/95115707?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2
https://www.cnblogs.com/xiaoxiaole/p/7457788.html
https://www.jianshu.com/p/4ef12eb46cbf

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值