【Java】JDK源码分析——StringBuffer

一.概述

StringBuffer是java中用来处理字符串的类。不同于String,StringBuffer保存的字符串可以进行修改,拼接,删除等操作。相比于StringBuilder,StringBuffer几乎所有方法都被synchronized关键字修饰,因此StringBuffer是线程安全的,同时效率也比StringBuilder低。
StringBuffer.java中的相关代码:

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

1.StringBuffer被final修饰,不能被继承。
2.继承了AbstractStringBuilder,StringBuffer中的方法基本都是通过AbstractStringBuilder实现。
3.实现了java.io.Serializable接口,可以进行序列化。
4. 实现了CharSequence接口,可以将字符串当成一个一个的字符处理。

二.源码分析

1.全局变量

StringBuffer.java中的相关代码:

	// 缓存,保存最后一次调用toString方法返回的字符串
	// 当StringBuffer内容发生变化,缓存被清除
	private transient char[] toStringCache; 

	static final long serialVersionUID = 3388685877147921107L; // 用于序列化

	// 需要序列化的字段,用于序列化
	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),
    	};

2.常用的构造方法

1)无参数

StringBuffer.java中的相关代码:

    public StringBuffer() {
        super(16);
	}

默认情况下,调用构造方法,会调用父类的构造方法,分配一个容量为16个字符空间。

2)参数为int

StringBuffer.java中的相关代码:

    public StringBuffer(int capacity) {
        super(capacity);
	}

调用父类方法,指定需要分配的空间的大小来进行分配。

3)参数为String

StringBuffer.java中的相关代码:

    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
	}

调用父类的方法,为字符串分配空间,同时再多分配出来16个字符大小的空间,防止之后字符串长度发生改变;保存字符串。

3.length方法

获取StringBuffer中字符串的长度。
StringBuffer.java中的相关代码:

    @Override
	public synchronized int length() {
    	// 返回已使用空间的数量,count为父类的全局变量
        return count;
	}

4.capacity方法

获取StringBuffer当前最大能保存的字符串的长度。
StringBuffer.java中的相关代码:

    @Override
	public synchronized int capacity() {
    	// 返回字符数组长度,value为父类的全局变量
        return value.length;
	}

5. ensureCapacity方法

对字符数组进行扩容,保证空间大小足够。
StringBuffer.java中的相关代码:

    @Override
	public synchronized void ensureCapacity(int minimumCapacity) {
    	// 调用父类的ensureCapacity方法
        super.ensureCapacity(minimumCapacity);
	}

6.trimToSize方法

缩容,对字符数组中没有使用的空间进行释放。
StringBuffer.java中的相关代码:

    @Override
	public synchronized void trimToSize() {
    	// 调用父类的trimToSize方法
        super.trimToSize();
	}

7. setLength方法

设置字符数组空间的大小。
StringBuffer.java中的相关代码:

    @Override
	public synchronized void setLength(int newLength) {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的setLength方法
        super.setLength(newLength);
	}

8. charAt方法

获取字符串中指定位置的字符。
StringBuffer.java中的相关代码:

    @Override
	public synchronized char charAt(int index) {
    	// 若指定位置小于0或指定位置超过了字符串的长度
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        // 返回指定位置的字符
        return value[index];
	}

9. setCharAt方法

设置字符串中指定位置index的字符为ch。
StringBuffer.java中的相关代码:

    @Override
	public synchronized void setCharAt(int index, char ch) {
    	// 若指定位置小于0或指定位置超过了字符串的长度
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        // 清除缓存
        toStringCache = null;
        // 设置字符
        value[index] = ch;
	}

10.append方法

向当前字符串后再拼接一个字符串。

1)参数为Object

StringBuffer.java中的相关代码:

    @Override
	public synchronized StringBuffer append(Object obj) {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的append方法
        super.append(String.valueOf(obj));
        // 返回
        return this;
	}

2)参数为String

StringBuffer.java中的相关代码:

    @Override
	public synchronized StringBuffer append(String str) {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的append方法
        super.append(str);
        // 返回
        return this;
	}

其它参数形式的append方法的执行流程,也都是先清除缓存,再调用父类的append方法,最后返回。

11.delete方法

删除字符串中start到end之间的字符。
StringBuffer.java中的相关代码:

    @Override
	public synchronized StringBuffer delete(int start, int end) {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的delete方法
        super.delete(start, end);
        // 返回
        return this;
	}

12.replace方法

将原字符串中start和end中的字符替换为字符串str。
StringBuffer.java中的相关代码:

    @Override
	public synchronized StringBuffer replace(int start, int end, String str) {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的replace方法
        super.replace(start, end, str);
        // 返回
        return this;
	}

13.substring方法

截取原字符串中从start开始到结束的字符串。
StringBuffer.java中的相关代码:

    @Override
	public synchronized String substring(int start) {
    	// 调用重载的方法。
        return substring(start, count);
	}

调用重载的substring方法。
截取原字符串中从start开始到end之间的字符串。
StringBuffer.java中的相关代码:

    @Override
	public synchronized String substring(int start, int end) {
    	// 调用父类的substring方法,并返回
        return super.substring(start, end);
	}

14.insert方法

在原字符串的offset位置插入字符串str。
StringBuffer.java中的相关代码:

    @Override
	public synchronized StringBuffer insert(int offset, String str) {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的insert方法
        super.insert(offset, str);
        // 返回
        return this;
	}

其它参数形式的insert方法的执行流程,也都是先清除缓存,再调用父类的insert方法,最后返回。

15.indexOf方法

返回源字符串中str字符串首次出现的位置。
StringBuffer.java中的相关代码:

    @Override
	public int indexOf(String str) {
    	// 调用父类的indexOf方法,并返回
        return super.indexOf(str);
	}

该方法没有被synchronized方法修饰,因为indexOf方法还有一个重载的方法是被synchronized修饰的,可以根据需求自行选择。
类似的,lastIndexOf方法也提供了两个方法,一个被synchronized修饰,一个没有被synchronized修饰的方法。

16. reverse方法

将字符串进行反转。
StringBuffer.java中的相关代码:

    @Override
	public synchronized StringBuffer reverse() {
    	// 清除缓存
        toStringCache = null;
        // 调用父类的reverse方法
        super.reverse();
        // 返回
        return this;
	}

17. toString方法

将StringBuffer对象转换为String对象。
StringBuffer.java中的相关代码:

    @Override
	public synchronized String toString() {
    	// 若缓存为空
        if (toStringCache == null) {
            // 创建缓存,复制保存当前字符串的值。
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        // 根据缓存内容,创建字符串并返回
        return new String(toStringCache, true);
	}

18. writeObject方法

对StringBuffer对象进行序列化。
StringBuffer.java中的相关代码:

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

19. readObject方法

对StringBuffer对象进行反序列化。
StringBuffer.java中的相关代码:

    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);
 	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值