StringBuilder類表示一個可變的字符序列。StringBuilder的API與StringBuffer互相兼容,但是StringBuilder是非線程安全的,在大多數實現中它比StringBuffer更快。
一、類定義
public final class StringBufferextends AbstractStringBuilderimplements java.io.Serializable, CharSequence
{...
}
StringBuilder類被 final 所修飾,因此不能被繼承。
StringBuilder類繼承于 AbstractStringBuilder類。實際上,AbstractStringBuilder類具體實現了可變字符序列的一系列操作,比如:append()、insert()、delete()、replace()、charAt()方法等。值得一提的是,StringBuffer也是繼承于AbstractStringBuilder類。
StringBuilder類實現了2個接口:
- Serializable 序列化接口,表示對象可以被序列化。
- CharSequence 字符序列接口,提供了幾個對字符序列進行只讀訪問的方法,比如:length()、charAt()、subSequence()、toString()方法等。
二、成員變量
private transient char[] toStringCache;// AbstractStringBuilder.javachar[] value;int count;
- value、count這兩個變量是繼承自父類
三、構造方法
//默認構造方法設置了value數組的初始容量為16。
public StringBuilder() {super(16);
}
//設置了value數組的初始容量為指定的大小。
public StringBuilder(int capacity) {super(capacity);
}
//接受一個String對象作為參數,設置了value數組的初始容量為String對象的長度+16,并把String對象中的字符添加到value數組中。
public StringBuilder(String str) {super(str.length() + 16);append(str);
}
//接受一個CharSequence對象作為參數,設置了value數組的初始容量為CharSequence對象的長度+16,并把CharSequence對象中的字符添加到value數組中。
public StringBuilder(CharSequence seq) {this(seq.length() + 16);append(seq);
}// AbstractStringBuilder.java
AbstractStringBuilder(int capacity) {value = new char[capacity];
}
StringBuilder類提供了4個構造方法。構造方法主要完成了對value數組的初始化。
四、普通方法
StringBuilder實現了AbstractStringBuilder和CharSequence,他的方法都來自于這兩個類,絕大部分都是通過super來調用的。
4.1、append()方法
@Override
public StringBuilder append(boolean b) {super.append(b);return this;
}// AbstractStringBuilder.java
public AbstractStringBuilder append(boolean b) {if (b) {ensureCapacityInternal(count + 4);value[count++] = 't';value[count++] = 'r';value[count++] = 'u';value[count++] = 'e';} else {ensureCapacityInternal(count + 5);value[count++] = 'f';value[count++] = 'a';value[count++] = 'l';value[count++] = 's';value[count++] = 'e';}return this;
} @Override
public StringBuilder append(String str) {super.append(str);return this;
}// AbstractStringBuilder.java
public AbstractStringBuilder append(String str) {if (str == null)return appendNull();int len = str.length();ensureCapacityInternal(count + len);str.getChars(0, len, value, count);count += len;return this;
}
調用了父類AbstractStringBuilder類中對應的方法。最后,append()方法返回了StringBuilder對象自身。
append()方法將指定參數類型的字符串表示形式追加到字符序列的末尾。它可以接受boolean、char、char[]、CharSequence、double、float、int、long、Object、String、StringBuffer這些類型的參數。這些方法最終都,以便用戶可以鏈式調用StringBuilder類中的方法。
AbstractStringBuilder類的各個append()方法大同小異。append()方法在追加字符到value數組中之前都會調用ensureCapacityInternal()方法來確保value數組有足夠的容量,然后才把字符追加到value數組中。
4.2、toString()方法
@Override
public String toString() {// Create a copy, don't share the arrayreturn new String(value, 0, count);
}
4.3、writeObject和readObject
/*** Save the state of the {@code StringBuilder} instance to a stream* (that is, serialize it).** @serialData the number of characters currently stored in the string* builder ({@code int}), followed by the characters in the* string builder ({@code char[]}). The length of the* {@code char} array may be greater than the number of* characters currently stored in the string builder, in which* case extra characters are ignored.*/private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {s.defaultWriteObject();s.writeInt(count);s.writeObject(value);}/*** readObject is called to restore the state of the StringBuffer from* a stream.*/private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {s.defaultReadObject();count = s.readInt();value = (char[]) s.readObject();}
實現自Serializable接口后,可定制的序列化過程
五、StringBuffer 與 StringBuilder
5.1、類繼承關系:
StringBuilder 和 StringBuffer是高度類似的兩個類,都是可變字符序列,他們都實現了AbstractStringBuilder
5.2、方法體系:
他們除了實現了AbstractStringBuilder 和 CharSequence外,實際上他們沒有自己的方法,所有的方法都來自AbstractStringBuilder 和 CharSequence
5.3、線程安全:
StringBuffer是線程安全的,StringBuilder是非線程安全的,其實線程安全也就是方法前面增加了一個synchronized關鍵字
toStringCache:StringBuffer中有一個toStringCache 就像它的名字一樣,toString()方法的cache
簡言之就是緩存toString方法的,每次調用toString會檢查這個字段,如果不為null將會使用它進行對象創建
如果為null 將會給他初始化賦值,也就是緩存,當調用其他的任何方法改變StringBuffer時,就會把toStringCache進行清空,如果每次都是更改變動后調用,顯然,還適得其反的浪費了性能
如果多次調用toString將會得到好處
5.4、總結
兩個類的功能邏輯上來說基本一樣,都是可變的字符序列
代碼的相似度也很高
他們本身就是為了做同一件事情
只不過是各自的側重點不同
他們都實現了AbstractStringBuilder和CharSequence
他們的方法都來自于這兩個類
只不過StringBuffer是線程安全的,StringBuilder非線程安全
其實 早在1.0版本StringBuffer 就已經存在了
StringBuffer則是在1.5才加入進來的,AbstractStringBuilder 也是在1.5加入進來
StringBuilder 就是 StringBuffer的一個非線程安全的實現
AbstractStringBuilder 也是后來才對類的設計進行抽象升華的
StringBuffer才實現了這個類
他們的源代碼也大多數是雷同的
主要差異就在于以下三點
StringBuffer覆蓋的方法略微多一點
StringBuffer 在方法上增加了synchronized關鍵字用于同步,亦或者應該說,StringBuilder去掉了synchronized
StringBuffer的toStringCache緩存
如果去掉這三點,這兩份代碼就幾乎是一樣的了
除非你的確非常確信你需要使用StringBuffer
否則,如果不可變使用String
如果可變使用StringBuilder ,盡可能的放棄StringBuffer 吧
總結起來就一句話
StringBuilder是StringBuffer的非同步版本就是版本改寫
能用StringBuilder就不要用StringBuffer。