String、StringBuffer、StringBuilder剖析

空夜發表於2019-05-10

Java中關於字串最常見的三種儲存形式是:StringStringBufferStringBuilder。它們都是物件,而非基本資料型別。

其中,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的。三者之間的區別在於:

  1. String利用final char[]儲存資料,而另外兩者則是char[]。這意味著String是不可變的,而StringBuilderStringBuffer則是可變的。

    這裡引用Matrix海子的一句話對此進行總結:對String物件的任何改變都不影響到原物件,相關的任何change操作都會生成新的物件

  2. 從執行緒安全性上看:String是常量,那就是執行緒安全的。StringBuilder的方法沒有加同步鎖,而StringBuffer的對方法加了同步鎖,所以StringBuilder是非執行緒安全的。

  3. 從效能上看,String發生改變時,總會建立新的String物件,而後將指標指向這個新的String物件。而java的垃圾收集是通過JVM的GC進行的,這樣就導致假如下一次GC還未啟動,已經產生了大量的不再被使用的String物件,那麼就會大大影響到系統效能。

    StringBuilder和StringBuffer都是對物件本身進行操作的,所以不會造成效能問題。相同情況下,使用StringBuilder比StringBuffer能獲得10%~15%的效能提升,但有可能會造成執行緒不安全問題。


三者的使用情況

總結String、StringBuilder和StringBuffer的使用情況:

  1. 在單執行緒情況下,如果字串change操作較少,建議使用String。如果change操作較多,建議使用StringBuilder——在idea開發環境中,如在一個for迴圈中連線字串,會自動提示應該使用StringBuilder的append而不是String本身。
  2. 在多執行緒情況下,如果字串change操作較少,同樣使用String。否則建議使用StringBuffer。

有關String、StringBuilder和StringBuffer的相關知識就總結到這裡。如有失誤,請諒解,歡迎大家指正!

參考:

  1. JavaGuide--String StringBuffer 和 StringBuilder 的區別是什麼? String 為什麼是不可變的?
  2. Matrix海子--探祕Java中的String、StringBuilder以及StringBuffer

相關文章