public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
{
.....
}
AbstractStringBuilder类:(这里仅简单介绍append方法简单,在这里细讲append,主要是在StringBuffer里直接调用父类的append,其他的类似。)
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.与String类一样,定义了一个char类型的数组存储值
*/
char value[];
/**
* The count is the number of characters used.
*/
int count;
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
public AbstractStringBuilder append(String str) {
if (str == null) str = "null";
int len = str.length();
if (len == 0) return this;
int newCount = count + len;
if (newCount > value.length)
expandCapacity(newCount);//这一步主要是扩容
str.getChars(0, len, value, count);
count = newCount;
return this;
}
void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;//首先定义一个是原容量的2倍大小的值
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {//这一步主要是判断,取最大的值做新的数组容量大小
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);//最后进行扩容
}
String类的getChar(...)函数:
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);
}
AbstractStringBuilder类里定义了很多方法,在StringBuffer里是直接通过supper.XXX()调用的,这里就不细说了。
再来看看CharSequence接口是个什么东东:
public interface CharSequence {
int length();
char charAt(int index);
CharSequence subSequence(int start, int end);
public String toString();
}
看到了吧,定义了几个公共的方法,这里就不多说了。
-------------------------------- 回到StringBuffer -------------------------------------------
先看看几个构造方法:
public StringBuffer() {
super(16);//定义一个长度为16的数组
}
/**
* Constructs a string buffer with no characters in it and
* the specified initial capacity.
*
* @param capacity the initial capacity.
* @exception NegativeArraySizeException if the capacity
* argument is less than 0
.
*/
public StringBuffer(int capacity) {
super(capacity);
}
/**
* Constructs a string buffer initialized to the contents of the
* specified string. The initial capacity of the string buffer is
* 16
plus the length of the string argument.
*
* @param str the initial contents of the buffer.
* @exception NullPointerException if str
is null
*/
public StringBuffer(String str) {
super(str.length() + 16);
append(str);//该方法在上面已经分析过
}
append()方法:
public synchronized StringBuffer append(String str) {
super.append(str);
return this;//从这里可以看出不管执行多少次的append(String)方法,不会与String的字符串拼接那样new String(...)对象。
}
append用的修饰符是synchronized,说明是线程安全的,而StringBuilder没有这个修饰符。
toString():
public synchronized String toString() {
return new String(value, 0, count);//相当于重新生成一个String对象
}
其他方法就不介绍了,大同小异。