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% 左右的效能提升,但卻要冒多執行緒不安全的風險。
對於三者使用的總結:
- 操作少量的資料: 適用String
- 單執行緒操作字串緩衝區下操作大量資料: 適用StringBuilder
- 多執行緒操作字串緩衝區下操作大量資料: 適用StringBuffer