String,StringBuffer,StringBuilder區別
阿新 • • 發佈:2020-12-26
目錄
一、 String 為什麼是不可變的?
String類中使用了final修飾字符陣列的,所以是不可以變的。
二、StringBuffer和StringBuilder區別
2.1 相同點
二者都是繼承了AbstractStringBuilder,在AbstractStringBuilder中我們可以發現沒有用final修飾字符陣列,所以二者都是可變的。原始碼如下:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
/**
* The count is the number of characters used.
*/
int count;
/**
* This no-arg constructor is necessary for serialization of subclasses.
*/
AbstractStringBuilder() {
}
/**
* Creates an AbstractStringBuilder of the specified capacity.
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
2.2 不同點
執行緒安全性
String 中的物件是不可變的,也就可以理解為常量,執行緒安全。
AbstractStringBuilder 是 StringBuilder 與 StringBuffer 的公共父類,定義了一些字串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 對方法加了同步鎖或者對呼叫的方法加了同步鎖,所以是執行緒安全的。
@Override
public synchronized StringBuffer append(char c) {
toStringCache = null;
super.append(c);
return this;
}
@Override
public synchronized StringBuffer append(int i) {
toStringCache = null;
super.append(i);
return this;
}
StringBuilder 並沒有對方法進行加同步鎖,所以是非執行緒安全的。
@Override
public StringBuilder append(char c) {
super.append(c);
return this;
}
@Override
public StringBuilder append(int i) {
super.append(i);
return this;
}
三、效能
每次對 String 型別進行改變的時候,並不是直接對物件本身進行操作而是會生成一個新的 String 物件,然後將指標指向新的 String 物件。
StringBuffer和StringBuilder每次都會對物件本身進行操作,而不是生成新的物件並改變物件引用。雖然在相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的效能提升,但卻要冒多執行緒不安全的風險。
四、總結
操作少量的資料: 適用 String
單執行緒操作字串緩衝區下操作大量資料: 適用 StringBuilder
多執行緒操作字串緩衝區下操作大量資料: 適用 StringBuffer