1. 程式人生 > >String、StringBuilder與StringBuffer

String、StringBuilder與StringBuffer

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是執行緒安全的。

總結
  1. 如果要操作少量的資料,用String即可;單執行緒環境下操作字串內容,用StringBuilder;多執行緒環境下操作字串內容,用StringBuffer。
  2. StringBuffer因為對每個操作字串的方法加鎖,故實際效能比StringBuilder低。
  3. 為了獲得更好的效能,在構造StringBuilder或者StringBuffer時應儘可能指定它們的容量。