Java中關於字串最常見的三種儲存形式是:String
、StringBuffer
、StringBuilder
。它們都是物件,而非基本資料型別。
其中,String
是最常見的一種用於定義和儲存字串的形式。
下面我們將分析一下這三種Object的區別和使用場景。
首先我們看一下這三個類的原始碼:
原始碼
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
private final char value[];
// ...
}
複製程式碼
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence {
//...
@Override
public synchronized int length() {
return count;
}
//...
}
複製程式碼
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence {
//...
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
//...
}
複製程式碼
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
}
複製程式碼
三者的區別
從原始碼可以發現,String、StringBuilder、StringBuffer都是用char陣列來儲存String的。三者之間的區別在於:
-
String
利用final char[]
儲存資料,而另外兩者則是char[]
。這意味著String是不可變的,而StringBuilder
和StringBuffer
則是可變的。這裡引用
Matrix海子
的一句話對此進行總結:對String物件的任何改變都不影響到原物件,相關的任何change操作都會生成新的物件
。 -
從執行緒安全性上看:String是常量,那就是執行緒安全的。StringBuilder的方法沒有加同步鎖,而StringBuffer的對方法加了同步鎖,所以StringBuilder是非執行緒安全的。
-
從效能上看,String發生改變時,總會建立新的String物件,而後將指標指向這個新的String物件。而java的垃圾收集是通過JVM的GC進行的,這樣就導致假如下一次GC還未啟動,已經產生了大量的不再被使用的String物件,那麼就會大大影響到系統效能。
StringBuilder和StringBuffer都是對物件本身進行操作的,所以不會造成效能問題。相同情況下,使用StringBuilder比StringBuffer能獲得10%~15%的效能提升,但有可能會造成執行緒不安全問題。
三者的使用情況
總結String、StringBuilder和StringBuffer的使用情況:
- 在單執行緒情況下,如果字串change操作較少,建議使用String。如果change操作較多,建議使用StringBuilder——在idea開發環境中,如在一個for迴圈中連線字串,會自動提示應該使用StringBuilder的append而不是String本身。
- 在多執行緒情況下,如果字串change操作較少,同樣使用String。否則建議使用StringBuffer。
有關String、StringBuilder和StringBuffer的相關知識就總結到這裡。如有失誤,請諒解,歡迎大家指正!
參考: