StringBuilder 是可变字符串类型,它被人所熟知的功能就是可以很方便的对字符串进行拼接、构造:
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence 方法是 final 的,继承了 AbstractStringBuilder 抽象类:
abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; ... } 可以看到它实现了 Appendable 接口,而 Appendable 接口就是提供了可以被添加char序列和值的功能,它实现了三种 append 方法:
Appendable append(CharSequence csq) throws IOException; Appendable append(CharSequence csq, int start, int end) throws IOException; Appendable append(char c) throws IOException; 其中 CharSequence 是 char 值的可读序列,此接口对许多不同种类的 char 序列提供统一的只读访问, String StringBuilder StringBuffer 都实现了这个接口:
int length(); char charAt(int index); CharSequence subSequence(int start, int end); 在 AbstractStringBuilder 抽象类中,提供了一系列的 append 和 insert 方法的实现,下面是其中一种实现:
public AbstractStringBuilder append(String str) { if (str == null) str = "null"; //如果为空,则添加null字符串 int len = str.length(); ensureCapacityInternal(count + len);//保证容量 //复制str字符串到char数组value,从count位开始添加 str.getChars(0, len, value, count); count += len; return this; } private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); } 如果传递的最小容量大于现有容量,则必须进行扩容:
void expandCapacity(int minimumCapacity) { //新容量为old*2+2 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); } 注意: AbstractStringBuilder 中的方法实现都没有进行同步
insert 方法:
public AbstractStringBuilder insert(int offset, String str) { if ((offset < 0) || (offset > length())) throw new StringIndexOutOfBoundsException(offset); if (str == null) str = "null"; int len = str.length(); ensureCapacityInternal(count + len); System.arraycopy(value, offset, value, offset + len, count - offset); str.getChars(value, offset); count += len; return this; } StringBuffe r类的出现实际上比 StringBuilder 要早,当初提供 StringBuilder 类只是为了提供一个单个线程使用的 StringBuffer 等价类。如果观察 StringBuffer 的源代码,可以发现它的方法和 StringBuilder 相同,只不过都加上了 synchronized ,比如:
public synchronized StringBuffer append(String str) { super.append(str); return this; } 现在我们已经明确的记住了 StringBuffer 是线程安全的,而 StringBuilder 不是
在效率上, StringBuffer 因为对方法做了同步,所以一般是低于 StringBuilder 的
二者都是可变的,因为二者都继承 AbstractStringBuilder ,它的 char[] value 没有使用 final 修饰,只是普通数组。 String 的 value 是 final 的,即不可变的
都有实现 CharSequence 接口