1. 程式人生 > 實用技巧 >String 和 StringBuffer、StringBuilder 的區別

String 和 StringBuffer、StringBuilder 的區別

可變性

簡單的來說:String 類中使用 final 關鍵字修飾字符陣列來儲存字串,private final char value[],所以 String 物件是不可變的。而StringBuilder 與 StringBuffer 都繼承自 AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字元陣列儲存字串char[]value但是沒有用 final 關鍵字修飾,所以這兩種物件都是可變的。

StringBuilder 與 StringBuffer 的構造方法都是呼叫父類構造方法也就是 AbstractStringBuilder 實現的,大家可以自行查閱原始碼。

AbstractStringBuilder.java

java
abstract class AbstractStringBuilder implements Appendable, CharSequence {
    char[] value;
    int count;
    AbstractStringBuilder() {
    }
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }

執行緒安全性

String 中的物件是不可變的,也就可以理解為常量,執行緒安全。AbstractStringBuilder 是 StringBuilder 與 StringBuffer 的公共父類,定義了一些字串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 對方法加了同步鎖或者對呼叫的方法加了同步鎖,所以是執行緒安全的。StringBuilder 並沒有對方法進行加同步鎖,所以是非執行緒安全的。 

效能

每次對 String 型別進行改變的時候,都會生成一個新的 String 物件,然後將指標指向新的 String 物件。StringBuffer 每次都會對 StringBuffer 物件本身進行操作,而不是生成新的物件並改變物件引用。相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的效能提升,但卻要冒多執行緒不安全的風險。

對於三者使用的總結:

  1. 操作少量的資料: 適用String
  2. 單執行緒操作字串緩衝區下操作大量資料: 適用StringBuilder
  3. 多執行緒操作字串緩衝區下操作大量資料: 適用StringBuffer