首先来看看StringBuffer的定义
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence {
private transient char[] toStringCache;
static final long serialVersionUID = 3388685877147921107L;
public StringBuffer() {
super(16);
}
public synchronized int length() {
return count;
}
定义成final形式,主要是为了“效率”和“安全性”的考虑.
其父类AbstractStringBuilder的定义如下:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* 存储字符串的字符数组,非final类型,区别于String类
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
//检查是否需要扩容
ensureCapacityInternal(count + len);
//字符串str拷贝至value
str.getChars(0, len, value, count);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
// minimumCapacity=count+str.length
//拼接上str后的容量 如果 大于value容量,则扩容
if (minimumCapacity - value.length > 0) {
//扩容,并将当前value值拷贝至扩容后的字符数组,返回新数组引用
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
//StringBuilder扩容
private int newCapacity(int minCapacity) {
// overflow-conscious code
// 计算扩容容量
// 默认扩容后的数组长度是按原数(value[])组长度的2倍再加上2的规则来扩展,为什么加2?
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
}
StringBuffer和StringBuilder用一样,内部维护的value[]字符数组都是可变的,区别只是StringBuffer是线程安全的,它对所有方法都做了同步,StringBuilder是线程非安全的,因此在多线程操作共享字符串变量的情况下字符串拼接处理首选用StringBuffer, 否则可以使用StringBuilder,毕竟线程同步也会带来一定的消耗。
网友评论