java StringBuffer StringBulider
StringBuffer 字符串变量(线程安全)
StringBuilder 字符串变量(非线程安全)
String 类型和 StringBuffer 、StringBuilder 类型的主要性能区别其实在于 String 是不可变的对象,而后俩者都是可变的。
来看看 StringBuffer类源码定义:
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuffer() {
super(16);
}
public StringBuffer(int capacity) {
super(capacity);
}
上例代码我们发现 StringBuffer 继承了 AbstractStringBuilder抽象类。包括构造方法的实现,都是父类提供的。
然后,我们打开 StringBuilder源码定义:
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
public StringBuilder() {
super(16);
}
public StringBuilder(int capacity) {
super(capacity);
}
我们发现两者都继承了AbstractStringBuilder抽象类。且构造方法都调用父类实现。
我们接着看两者append方法实现:
先看StringBuffer的:
public synchronized StringBuffer append(Object obj) {
super.append(String.valueOf(obj));
return this;
}
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
//...
再看StringBuilder的:
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
public StringBuilder append(String str) {
super.append(str);
return this;
}
//...
对比上面两段源码 我们发现 StirngBuffer 和StringBuilder的 append实现都是调用父类实现的。唯一不同的是 StringBuffer是线程安全的,方法中多了synchronized ,而StringBuilder 是非线程安全的。
我们看下父类AbstractStringBuilder 定义 及 append 实现:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
//底层与String类一样都是 char类型数组。
char value[];
//字符串长度
int count;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
public AbstractStringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
public AbstractStringBuilder append(String str) {
//对于str==null的
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
//新的字符串长度
int newCount = count + len;
if (newCount > value.length)
//当新的字符串长度比原先数组长度大时,需要对char 数组扩容。
expandCapacity(newCount);
//将新添的数据追加到char类型数组中。
str.getChars(0, len, value, count);
count = newCount;
return this;
}
//数组扩容
void expandCapacity(int minimumCapacity) {
//先扩容成 (原先的长度+1)*2
int newCapacity = (value.length + 1) * 2;
//判断newCapacity值是否满足要求
//如果新的长度还是不够,则直接取值 minimumCapacity
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
char newValue[] = new char[newCapacity];
//将原先的数据拷贝到新的char 数组中。
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
}
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > count) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
System.arraycopy(value, offset + srcBegin, dst, dstBegin,
srcEnd - srcBegin);
}