StringBuilder内存原理分析

本文深入剖析了Java中StringBuilder的内存原理,包括无参数和有参数构造函数的行为,详细解释了扩容机制,并通过内存图展示了扩容过程。还对比了StringBuilder与StringBuffer的差异和联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

StringBuilder是可变字符串。String是不可变字符串。
StringBuilder内存原理分析:
StringBuilder 是java.lang包下的。继承自AbstractStringBuilder
在这里插入图片描述
在这里插入图片描述
其中AbstractStringBuilder种有两个属性:

/**
 * The value is used for character storage.
 */
 char[] value;   //字符数组用于字符存储。
/**
 * The count is the number of characters used.
 */
int count;  //count是使用的字符数。

StringBuilder类介绍到这,下面给大家介绍一下内存分析。代码如下。

public class Test01 {
    public static void main(String[] args) {
//        String str = "abc";
        StringBuilder sb= new StringBuilder();
        StringBuilder sb1 = new StringBuilder("abc");
        System.out.println(sb == sb1);
    }
}

一:先介绍一下无参数的stringBuilder()
stringBuilder类中无惨构造函数,
StringBuilder sb= new StringBuilder();

public StringBuilder() {
				    super(16);
				}

通过supper(16)调用父类的
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
由此可见AbstractStringBuilder中char[] value = new char[16];
二:以有参为例画内存图:
StringBuilder sb1 = new StringBuilder(“abc”);
在这里插入图片描述
在继续走父类AbstractStringBuilder
在这里插入图片描述
char[] value = new char[19];
由此可见无惨数的默认长度为16.有参数的长度为传入的长度+16

继续走append(str)方法
在这里插入图片描述
走父类的

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

执行顺序:
1.if不成立,走下面
2.len = str.length(); //str是我们传入‘abc’所以长度为3
3.走到ensureCapacityInternal(count + len)其中count默认为0,len=3;
其中做个判断。
第一种情况不成立,
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)//3-19 >0不成立
expandCapacity(minimumCapacity);
}
所以不走第三步。
第二种情况
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)//成立
expandCapacity(minimumCapacity);
}
成立的情况下走
在这里插入图片描述
此时会对数组进行一个扩容(原数组长度19*2+2=40)。画图做一个模拟扩容。

4.走 str.getChars(0, len, value, count);
3 19 0
对应的值分别为 0 3 19 0
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}

其中if是一些异常的判断。此处不解释。介绍
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
//分别对应的值 3 0 19 0 3-0=3
就是从‘abc’数组中下标为0开始复制到长度为19的那个字符数组中去(char[] value = new char[19]; )复制3个长度。到此执行完毕走下一步
5. count += len; //0+3=3;count的长度改变为3
6. return this;谁调用的返回谁。
内存分析图如下 没扩容数组长度没有超过19长度
在这里插入图片描述
扩容后的数组。
在这里插入图片描述
此时的扩容会牵扯到数组最大值和最小值。
扩容到最大值
Int MAX_VALUE 值为 231-1 的常量,它表示 int 类型能够表示的最大值。
Int MIN_VALUE 值为 -231 的常量,它表示 int 类型能够表示的最小值。
(暂时理解了这么多。就此写到这。后续有理解在继续更新…)
StringBuilder :JDK1.5开始,效率高,线程不安全
StringBuffer: JDK1.0开始,效率低,线程安全
联系:查看stringbuffer源码,底层依旧是数组扩容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值