Java_String_正確使用String、StringBuffer、StringBuilder

CharSequence接口有三個實現類與字符串有關:String、StringBuffer、StringBuilder,雖然它們都與字符串有關,但是其處理機制是不同的。
String類是不可改變的量,也就是創建後就不能修改了,比如創建了一個“abc”這樣的字符串對象,那麼它在內存中永遠都會是“abc”這樣具有固定表面值的一個對象,不能被修改,即使想通過String提供的方法來嘗試修改,也是要麼創建一個新的字符串對象,要麼返回自己,比如:

package deep;

public class Client {

    public static void main(String[] args) {
        String str = "abc";
        String str1 = str.substring(1);
        System.out.println(str1);
    }

}

運行結果:
bc

其中,str是一個字符串對象,其值是“abc”,通過substring方法產生了一個字符串str1,它的值是“bc”,也就是說str引用的對象一旦產生就永遠不會改變。爲什麼上面還說有可能不創建對象而返回自己呢?那是因爲採用了str.substring(0)就不會創建新對象,JVM會從字符串池中返回str的引用,也就是自身的引用。
StringBuffer是一個可變字符序列,它與String一樣,在內存中保存的都是一個有序的字符序列(char類型的數組),不同點是StringBuffer對象的值是可改變的,例如:

        StringBuffer sb = new StringBuffer("a");
        sb.append("b");

從上面的代碼可以看出sb的值在改變,初始化的時候是“a”,經過append方法後,其值變成了“ab”。可能有讀者會問了,這與String類通過“+”連接有什麼區別?例如:

        String s = "a";
        s = s + "b";

有區別,字符串變量s的初始化時是“a”對象的引用,經過加號計算後,s變量就修改爲了“ab”的引用,但是初始化的“a”的對象還是沒有改變,只是變量s指向了新的引用地址。再看看StringBuffer的對象,它的引用地址雖不變,但值在改變。
StringBuilder與StringBuffer基本相同,都是可變字符序列,不同點是:StringBuffer是線程安全的,StringBuilder是線程不安全的,翻翻兩者的源代碼,就會發現在在StringBuffer的方法前都有synchronized關鍵字,這也是StringBuffer在性能上遠低於StringBuilder的原因。
在性能方面,由於String類的操作都是產生新的String對象,而StringBuilder和StringBuffer只是一個字符數組的再擴容而已,所以String類的操作要遠慢於StringBuffer和StringBuilder。
弄清楚了三者的原理,我們就可以在不同的場景下使用不同的字符序列了:

  1. 使用String的場景
    在字符串不經常變化的場景中可以使用String類,例如常量的聲明、少量的變量運算等。
  2. 使用StringBuffer類的場景
    在頻繁進行字符串的運算(如拼接、替換、刪除等),並且運行在多線程的環境中,則可以考慮使用StringBuffer,例如XML解析、HTTP參數解析和封裝等。
  3. 使用StringBuilder的場景
    在頻繁進行字符串的運算(如拼接、替換、刪除等),並且運行在單線程的環境中,則可以考慮使用StringBuilder,如SQL語句的拼裝、JSON封裝等。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章