StringBuilder内存原理分析

StringBuilder是可变字符串。String是不可变字符串。
StringBuilder内存原理分析:
StringBuilder 是java.lang包下的。继承自AbstractStringBuilder
StringBuilder内存原理分析_第1张图片
StringBuilder内存原理分析_第2张图片
其中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”);
StringBuilder内存原理分析_第3张图片
在继续走父类AbstractStringBuilder
StringBuilder内存原理分析_第4张图片
char[] value = new char[19];
由此可见无惨数的默认长度为16.有参数的长度为传入的长度+16

继续走append(str)方法
StringBuilder内存原理分析_第5张图片
走父类的

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);
}
成立的情况下走
StringBuilder内存原理分析_第6张图片
此时会对数组进行一个扩容(原数组长度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长度
StringBuilder内存原理分析_第7张图片
扩容后的数组。
StringBuilder内存原理分析_第8张图片
此时的扩容会牵扯到数组最大值和最小值。
扩容到最大值
Int MAX_VALUE 值为 231-1 的常量,它表示 int 类型能够表示的最大值。
Int MIN_VALUE 值为 -231 的常量,它表示 int 类型能够表示的最小值。
(暂时理解了这么多。就此写到这。后续有理解在继续更新…)
StringBuilder :JDK1.5开始,效率高,线程不安全
StringBuffer: JDK1.0开始,效率低,线程安全
联系:查看stringbuffer源码,底层依旧是数组扩容。

你可能感兴趣的:(java基础)