Java8源码 java.lang 包 04、04.StringBuffer 和 StringBuilder

概述

StringBuilder 从类名语义上来说 String 构建者,用来创建 String 的。在 java 开发中经常用到 String 处理字符串,但 String 对象是一个常量,一旦创建后不能改变,所以无法对其进行修改操作,对 String 对象的操作,实际上是不断的创建新的 String 对象。当需要对字符串的值进行频繁修改时,就需要使用 StringBuffer 和 StringBuilder 了。

StringBuilder

类的定义

 public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

构造方法

无参构造方法

    public StringBuilder() {
        super(16);	// 调用父类的构造方法,初始容量为16个字符
    }

String参数构造方法

    public StringBuilder(String str) {
        super(str.length() + 16);	//调用父类的构造方法,初始容量为字符串长度加16个字符
        append(str);
    }

int参数构造方法

    public StringBuilder(int capacity) {
        super(capacity);	//调用父类的构造方法,初始容量为指定大小.
    }

CharSequence参数构造方法

  public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);	// 调用int参数构造方法
        append(seq);
    }

其他方法

writeObject

	// 在进行序列化的时候保存StringBuilder对象的状态到一个流中  
	private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        s.defaultWriteObject();
        s.writeInt(count);
        s.writeObject(value);
    }	

readObject

	//	在进行反序列化时从流中获取StringBuild对象序列化之前的状态   
	private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        count = s.readInt();
        value = (char[]) s.readObject();
    }

toString

实现父类的抽象方法

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

返回 StringBuilder 对象的字符串形式,创建了一个新的字符串对象,代码注释说了创建一个副本,而不要去共享这个内部维护的数组。因为返回的是 String 对象,是不可变的,如果返回的是共享的数组,在改变 StringBuilder 对象时,String 对象的内容随之改变,这就破坏了 String 对象的不可变性。

其他

StringBuilder 类中其它的方法都属于重写或继承自父类 AbstractStringBuilder 中的方法,重写的方法就是简单的调用了父类的实现而已。比如 append 方法:

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

需要注意一点的是 StringBuilder 是线程不安全的,在单线程程序中使用效率会高很多。在多线程程序中要慎用。

StringBuffer

StringBuffer 类也是用来构建动态 String 对象的,但与 StringBuilder 不同的是 StringBuffer 是线程安全的。

类的定义

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

成员变量

    private transient char[] toStringCache;

toStringCache 变量用于缓存 StringBuffer 对象维护的字符数组,作用是保证线程操作 StringBuffer 对象时都能让 toString 方法表现出相同的结果。

构造方法

同 StringBuilder 中的构造方法

其他方法

writeObject

   //  在进行序列化的时候保存StringBuffer对象的状态到一个流中   
    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

	//	在进行反序列化时从流中获取StringBuffer对象序列化之前的状态。    
	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);
    }

toString

实现父类的抽象方法

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

实现 CharSequence 接口的方法

    @Override
    public synchronized int length() {
        return count;
    }
    
    @Override
    public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }
    
    @Override
    public synchronized CharSequence subSequence(int start, int end) {
        return super.substring(start, end);
    }
    
    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

重写的方法

StringBuffer 在重写父类 AbstractStringBuilder 的方法时,通过在方法上加上 synchronized 来保证线程安全。其实现逻辑就是简单的调用父类的实现而已。比如 append 方法:

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

如果数组发生了增删改操作,需要先清楚字符数组变量 toStringCache

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值