首先我们来看两个类的继承体系:
public final class StringBuilder extends AbstractStringBuilder implements
Appendable, CharSequence, Serializable;
public final class StringBuffer extends AbstractStringBuilder implements
Appendable, Serializable, CharSequence
二者基本类似,我们看AbstravtStringBuilder这个类
private char[] value;
static final int INITIAL_CAPACITY = 16;
AbstractStringBuilder() {
value = new char[INITIAL_CAPACITY];
}
AbstractStringBuilder(int capacity) {
if (capacity < 0) {
throw new NegativeArraySizeException(Integer.toString(capacity));
}
value = new char[capacity];
}
AbstractStringBuilder(String string) {
count = string.length();
shared = false;
value = new char[count + INITIAL_CAPACITY];
string.getCharsNoCheck(0, count, value, 0);
}
默认初始容量为16,当然我们也可以自己设置容量大小;接着我们看看拼接过程
final void append0(char[] chars) {
int newCount = count + chars.length;
if (newCount > value.length) {
enlargeBuffer(newCount);
}
System.arraycopy(chars, 0, value, count, chars.length);
count = newCount;
}
接下来我们看看扩容过程,
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 ,容量如果不够,直接扩充到需要的容量大小。所以我们在创建SB的时候,可以估算新字符串的长度来适当避免多次扩容,影响效率。
接着我们来看看StringBuffer的append方法
public synchronized StringBuffer append(char[] chars) {
append0(chars);
return this;
}
和StringBuilder的append方法
`
public StringBuilder append(char c) {
append0(c);
return this;
}
这就是一个线程安全而另一个线程不安全的原因`