StringBuffer与StringBuilder非常类似,两者的很多实现方式上都是一样的,先看两者的继承层次
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{...}
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{...}
通过两者的定义可以看出,继承层次是相同的,实现了Serializable接口可以串行化,实现CharSequence说明StringBuffer类似于字符串,CharSequence其实是和字符串有关的一系列操作,而两者共同的父类AbstractStringBuilder是很重要的,两者的很多操作其实在内部都是调用父类的操作,首先看AbstractStringBuilder这个类的域:
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
value就是实际字符串的存取位置,这个生命和String的value域声明差别在于String的value是final类型的,不可变,而AbstractStringBuilder的value无特殊声明,这样就可以通过value来修改存储的数据。剩下的比较重要的方法就是append和insert方法,这两个方法占据了这个类大部分内容,主要就是重载了各种类型,使得附加、插入字符串更加方便。知道了AbstractStringBuilder里面的内容之后,让我们看一下StringBuilder类中的方法。
构造函数
public StringBuffer() {
super(16);//构建父类,默认16个字符的大小
}
public StringBuffer(int capacity) {
super(capacity);
}
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
append方法
public synchronized StringBuffer append(StringBuffer sb) {
toStringCache = null;
super.append(sb);
return this;
}
StringBuffer的append方法其实就是调用了AbstractStringBuilder类的append方法,如果已有的value数组太小,则扩容,扩容的原则是oldCapacity*2+2,注意到append方法带有synchronized 关键字,说明这个方法是同步的,而StringBuilder的append就不是同步的,不是线程安全的。
insert方法
public synchronized StringBuffer insert(int offset, String str) {
toStringCache = null;
super.insert(offset, str);
return this;
}
public StringBuffer insert(int offset, int i) {
super.insert(offset, i);
return this;
}
类似于append方法,insert方法在内部也是调用父类的append方法,但是注意到,StringBuffer的append方法都是同步的,但是insert方法只有一部分是同步的,这是为什么呢?原因是不是synchronized的insert方法最终调用的都是synchronized的insert方法,比如:insert(int offset, int i)是将int值转变成String对象,然后调用同步的insert(int offset, String str)这个方法来实现insert。其实append方法也可以用这种方法实现,但是不知道为什么设计者并没有这么做。