String、StringBuilder與StringBuffer
阿新 • • 發佈:2018-12-26
String
String類的部分原始碼:
public final class String {
private final char value[];
public String() {
this.value = new char[0];
}
public String(String original) {
/*把字串分割成字元陣列並賦值給value[]*/
}
}
可以看出:
(1)String被final修飾,不可繼承。
(2)String中的字元陣列value[]被final修飾,且只能被賦值一次,這是String為不可變物件的原因。每次對String控制代碼進行改變的時候,都會生成一個新的String物件,並將指標指向新的String物件。
StringBuilder與StringBuffer
StringBuilder與StringBuffer類的部分原始碼:
public final class StringBuilder extends AbstractStringBuilder { char[] value;//繼承於父類AbstractStringBuilder<span style="white-space:pre"> </span> public StringBuilder() { super(16); } public StringBuilder(String str) { super(str.length() + 16); append(str); } public StringBuilder append(String str) { super.append(str); return this; } }
可以看出:public final class StringBuffer extends AbstractStringBuilder { char[] value;//繼承於父類AbstractStringBuilder public StringBuffer() { super(16); } public StringBuffer(String str) { super(str.length() + 16); append(str); } public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } }
(1)StringBuilder與StringBuffer共同繼承於父類AbstractStringBuilder。
(2)父類中的value[]並沒有被final修飾,是一個很普通的陣列,這就為後來的擴充套件提供了保障,此即StringBuilder和StringBuffer為可變物件的原因。可以通過append()方法將新字串追加至value[]末尾。
(3)構造方法中將16作為字元陣列的初始容量,當容量不足時,父類方法expandCapacity()會對字元陣列進行擴容,為其指定新的長度並將舊字元陣列中的資料copyOf到新字元陣列中。
(4)StringBuffer類中,對字串進行操作的主要方法都加了synchronized修飾符,而StringBuilder沒有,故StringBuffer是執行緒安全的。
總結
- 如果要操作少量的資料,用String即可;單執行緒環境下操作字串內容,用StringBuilder;多執行緒環境下操作字串內容,用StringBuffer。
- StringBuffer因為對每個操作字串的方法加鎖,故實際效能比StringBuilder低。
- 為了獲得更好的效能,在構造StringBuilder或者StringBuffer時應儘可能指定它們的容量。