1. 程式人生 > >Java開發者如何正確的使用String,StringBuffer,StringBuilder類

Java開發者如何正確的使用String,StringBuffer,StringBuilder類

通過前面的文章,我們知道String類最大的特點是不可變性,這意味著對String類的任何修改都會新生成一個字串,比如你執行了String類的substring,replace,toUpperCase,toLowerCase,trim方法都會生成一個新的字串,一旦你的程式對字串有大量修改,那麼在jvm的堆記憶體中就會生成大量的舊的臨時垃圾字串物件,如何解決這一問題呢?

答案是使用StringBuffer或者StringBuilder類,其中StringBuffer是一箇舊類,而StringBuilder是在JDK5中新增的一個類。

這裡面就涉及一個比較常見的話題,也是java開發者論壇被提問最多的一個問題,在Java裡面String,StringBuffer,StringBuilder的區別和聯絡。

在回答這個問題之前,我們先來看一些String類的基本特點:

(1)string是不可變的,帶來的好處主要有兩點,第一是執行緒安全,可以在多個執行緒中共享而不需要加鎖,第二是由於不變性所以它的hashcode可以被快取後提升效率,這也是為什麼我們見到的大多數的HashMap的key都是使用String型別的。

(2)通過雙引號定義的字串我們稱為字串字面量,這部分字串會被在string pool中建立,在java裡面比較一個物件相等,應該優先選擇equals方法而不是==方法

(3)對於字串拼接的 + 號,底層其實是使用StringBuffer 或者 StringBuilder來完成的。

看下面一個案例:

        String s1="a";
        String s2="b";

        String s3=s1+s2; // internal use StringBuffer orStringBuilder  create new String Object
        String s4="ab";

        System.out.println(s3==s4);//false

但如果使用final修飾後,jvm層面會直接優化成一個字串字面量,這一點需要特別注意,所以下面程式碼的結果會返回true:

        final String s1="a";
        final
String s2="b"; String s3=s1+s2; String s4="ab"; System.out.println(s3==s4);//true

(4)通過toString方法,可以把StringBuffer,StringBuilder轉成String,通過構造方法可以把String轉成StringBuffer,StringBuilder,但不能通過強制轉換來操作這三個類,即使他們處於同一類繼承層次下,否則會丟擲java.lang.ClasscastException異常。

關於StringBuffer,StringBuilder的區別非常簡單,大家僅僅需要記住StringBuffer是執行緒安全和同步的而StringBuilder則不是執行緒安全和非同步的即可,同時因為StringBuffer是執行緒執行緒安全的,所以它的效能低於StringBuilder類的。

結論:

String類是不可變的,但是StringBuffer,StringBuilder是可變的。StringBuffer是同步的,所以它的效能低於StringBuilder。連線操作符 + 號,底層是使用StringBuffer或者StringBuilder實現的。

那麼在日常開發中,應該如何選擇一個合適的字串操作類呢?

如果瞭解上面的內容,其實就很容易回答了:

(1)如果你要求字串不可變,那麼應該選擇String類

(2)如果你需要字串可變並且是執行緒安全的,那麼你應該選擇StringBuffer類

(3)如果你要求字串可變並且不存線上程安全問題,那麼你應該選擇StringBuilder類