StringBuffer与StringBuilder的异同
看代码
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
可以看出,StringBuffer与StringBuilder都继承了AbstractStringBuilder并都实现了Serializable, CharSequence
构造函数:
可以看出,StringBuffer与StringBuilder 构造函数的是一样的,点击查看源码可以发现,其实现都是调用了父类AbstractStringBuilder的构造函数,代码如下:
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
进入源码查看,会发现
- StringBuffer的方法都用synchronized做了修饰,所以StringBuffer是线程安全的,适用于多线程操作字符串缓冲区下操作大量数据
- StringBuilder的方法没有被synchronized做修饰,所以StringBuilder是非线程安全的,适用于单线程字符串缓冲区下操作大量数据
常用方法 append 分析
查看发现 append有很多,这里只看下常用的
代码如下:
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;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
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);
}
可以看出 AbstractStringBuilder 的扩容方式是 (当前长度*2+2) 如果该长度还是不够存储 则扩容后的长度为(原始长度+新字符串长度)