String、StringBuilder、StringBuffer三者的區別


  StringBuffer、StringBuilder和String都可以用來代表字符串。String類是不可變類,任何對String的改變都會引發新的String對象的生成;StringBuffer、StringBuilder則是可變類,任何對它所指代的字符串的改變都不會產生新的對象。

這三個類之間的區別主要是在兩個方面:線程安全和運行速度。

  1、線程安全

  String 字符串常量
  StringBuffer 字符串變量(線程安全)
  StringBuilder 字符串變量(非線程安全)
   簡要的說, String 類型和 StringBuffer 類型的主要性能區別其實在於 String 是不可變的對象, 因此在每次對 String 類型進行改變的時候其實都等同於生成了一個新的 String 對象,然后將指針指向新的 String 對象,所以經常改變內容的字符串最好不要用 String ,因為每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以后, JVM 的 GC 就會開始工作,那速度是一定會相當慢的。而如果是使用 StringBuffer 類則結果就不一樣了,每次結果都會對 StringBuffer 對象本身進行操作,而不是生成新的對象,再改變對象引用。所以在一般情況下我們推薦使用 StringBuffer ,特別是字符串對象經常改變的情況下。

  如果一個StringBuffer對象在字符串緩沖區被多個線程使用時,StringBuffer中很多方法可以帶有synchronized關鍵字,所以可以保證線程是安全的,但StringBuilder的方法則沒有該關鍵字,所以不能保證線程安全,有可能會出現一些錯誤的操作。所以如果要進行的操作是多線程的,那么就要使用StringBuffer,但是在單線程的情況下,還是建議使用速度比較快的StringBuilder。

  2、運行速度

  運行速度,又叫做執行速度,三者的運行速度比較結果為:StringBuilder > StringBuffer > String

  String最慢的原因:String為字符串常量,而StringBuilder和StringBuffer均為字符串變量,即String對象一旦創建之后該對象是不可更改的,但后兩者的對象是變量,是可以更改的。以下面一段代碼為例: 

1 String str="abc";
2 System.out.println(str);
3 str=str+"de";
4 System.out.println(str);

   如果運行這段代碼會發現先輸出“abc”,然后又輸出“abcde”,好像是str這個對象被更改了,其實,這只是一種假象罷了,JVM對於這幾行代碼是這樣處理的,首先創建一個String對象str,並把“abc”賦值給str,然后在第三行中,其實JVM又創建了一個新的對象也名為str,然后再把原來的str的值和“de”加起來再賦值給新的str,而原來的str就會被JVM的垃圾回收機制(GC)給回收掉了,所以,str實際上並沒有被更改,也就是前面說的String對象一旦創建之后就不可更改了。所以,Java中對String對象進行的操作實際上是一個不斷創建新的對象並且將舊的對象回收的一個過程,所以執行速度很慢。

  而StringBuilder和StringBuffer的對象是變量,對變量進行操作就是直接對該對象進行更改,而不進行創建和回收的操作,所以速度要比String快很多。StringBuffer和StringBuilder相比較,StringBuffer是線程安全的可變字符序列,一般線程安全必然會帶來效率問題;而StringBuilder是線程不安全的可變的字符序列,運行比較快。

  另外,有時候我們會這樣對字符串進行賦值

1 String str="abc"+"de";
2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
3 System.out.println(str);
4 System.out.println(stringBuilder.toString());

  這樣輸出結果也是“abcde”和“abcde”,但是String的速度卻比StringBuilder的反應速度要快很多,這是因為第1行中的操作和

  String str="abcde";

  是完全一樣的,所以會很快,而如果寫成下面這種形式

1 String str1="abc";
2 String str2="de";
3 String str=str1+str2;

  那么JVM就會像上面說的那樣,不斷的創建、回收對象來進行這個操作了,速度就會很慢。

  3、應用場景

  String:適用於少量的字符串操作的情況

  StringBuilder:適用於單線程下在字符緩沖區進行大量操作的情況

  StringBuffer:適用多線程下在字符緩沖區進行大量操作的情況

 

參考:

  https://www.cnblogs.com/su-feng/p/6659064.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM