Java中關於字符串最多見的三種存儲形式是:String
、StringBuffer
、StringBuilder
。它們都是對象,而非基本數據類型。html
其中,String
是最多見的一種用於定義和存儲字符串的形式。java
下面咱們將分析一下這三種Object的區別和使用場景。git
首先咱們看一下這三個類的源碼:github
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是非線程安全的。app
從性能上看,String發生改變時,總會建立新的String對象,然後將指針指向這個新的String對象。而java的垃圾收集是經過JVM的GC進行的,這樣就致使假以下一次GC還未啓動,已經產生了大量的再也不被使用的String對象,那麼就會大大影響到系統性能。ide
StringBuilder和StringBuffer都是對對象自己進行操做的,因此不會形成性能問題。相同狀況下,使用StringBuilder比StringBuffer能得到10%~15%的性能提高,但有可能會形成線程不安全問題。性能
總結String、StringBuilder和StringBuffer的使用狀況:
有關String、StringBuilder和StringBuffer的相關知識就總結到這裏。若有失誤,請諒解,歡迎你們指正!
參考: