StringBulider和StringBuffer的底层源码剖析

要深入了解 StringBuffer 和 StringBuilder 的区别,从底层源码的角度来解析,包括它们的创建、扩容机制等,可以参考 JDK 1.8 的源码。

1. AbstractStringBuilder 类
StringBuffer 和 StringBuilder 都继承自 AbstractStringBuilder。这个类包含了字符串操作的核心逻辑。

AbstractStringBuilder 源码

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value;
    int count;

    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

    AbstractStringBuilder() {
    }

    public int length() {
        return count;
    }

    public int capacity() {
        return value.length;
    }

    public void ensureCapacity(int minimumCapacity) {
        if (minimumCapacity > value.length) {
            expandCapacity(minimumCapacity);
        }
    }

    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity < minimumCapacity) {
            newCapacity = minimumCapacity;
        }
        value = Arrays.copyOf(value, newCapacity);
    }

    public AbstractStringBuilder append(String str) {
        if (str == null)
            str = "null";
        int len = str.length();
        ensureCapacity(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

    // ... 其他方法 ...
}

2. StringBuilder 类
StringBuilder 继承了 AbstractStringBuilder,并且不做任何同步处理。

StringBuilder 源码

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
    public StringBuilder() {
        super(16);
    }

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

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

    // 所有的方法都继承自 AbstractStringBuilder,不进行同步
}

3. StringBuffer 类
StringBuffer 继承了 AbstractStringBuilder,并且对所有方法都进行同步处理,以确保线程安全。

StringBuffer 源码

public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence {
    public StringBuffer() {
        super(16);
    }

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

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

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

    // 所有的方法都进行同步处理
}

4. 扩容机制
扩容机制在 AbstractStringBuilder 中实现。它的核心方法是 expandCapacity,具体如下:

expandCapacity 方法

void expandCapacity(int minimumCapacity) {
    int newCapacity = value.length * 2 + 2;
    if (newCapacity < minimumCapacity) {
        newCapacity = minimumCapacity;
    }
    value = Arrays.copyOf(value, newCapacity);
}

初始容量:newCapacity = value.length * 2 + 2,每次扩容时容量会变成原来的两倍加2。
如果新容量小于所需的最小容量,则将新容量设置为最小容量。
通过 Arrays.copyOf 方法将原数组复制到新数组中,并将 value 指向新数组。

5. 创建过程
StringBuilder 创建 

StringBuilder sb = new StringBuilder();

调用无参构造函数,初始容量为16。
super(16) 调用 AbstractStringBuilder 的构造函数,value 数组长度为16。

StringBuffer 创建 

StringBuffer sb = new StringBuffer();

调用无参构造函数,初始容量为16。
super(16) 调用 AbstractStringBuilder 的构造函数,value 数组长度为16。

6. 扩容示例
假设我们创建一个 StringBuilder,初始容量为16,并向其中添加超过16个字符: 

StringBuilder sb = new StringBuilder();
sb.append("12345678901234567"); // 17个字符

ensureCapacity 方法会检查是否需要扩容。
当前容量是16,不足以容纳17个字符,因此调用 expandCapacity。
计算新容量:newCapacity = 16 * 2 + 2 = 34。
新数组长度为34,原数组内容复制到新数组中。

总结: 

StringBuilder 和 StringBuffer 都继承自 AbstractStringBuilder,并共享其核心实现,包括初始容量和扩容机制。
线程安全性:StringBuilder 不进行同步处理,而 StringBuffer 对所有方法都进行同步处理。
扩容机制:扩容策略是原数组长度的两倍加2,当容量不足时扩容,并通过 Arrays.copyOf 方法复制原数组内容。

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值