首先,查看一下二者的继承体系,都继承自抽象类AbstractStringBuilder
下面是AbstractStringBuilder类的有参数构造器
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
在新建StringBuilder和StringBuffer的会后都会调用父类的构造器,默认长度为16public StringBuilder() {
super(16);
}
public StringBuffer() {
super(16);
}
有参数构造器public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
再说他他们的扩容:使用append()方法在字符串后面追加方法的时候,如果长度超过了字符串的存储空间,就需要扩容,扩容的方式就是构建新的字符串将新的复制过去,在进行字符串append添加的时候,会先计算添加后字符串大小,传入一个方法:ensureCapacityInternal 这个方法进行是否扩容的判断,需要扩容就调用expandCapacity方法进行扩容:
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}
先尝试将容量夸大至2倍+2,如果还是不够,则直接扩容至需要的大小,
最后上测试代码
public static void main(String[] args) {
//1:调用无参数构造器
StringBuffer str = new StringBuffer();
str.append("12345");
System.out.println(str.capacity());//16
System.out.println(str.length());//5
str.append("67890123456");
System.out.println(str.capacity());//16
System.out.println(str.length());//16
str.append("1");
System.out.println(str.capacity());//34
System.out.println(str.length());//17
//2:调用有参数构造器
str = new StringBuffer("123");
System.out.println(str.capacity());//19
System.out.println(str.length());//3
}