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
接口