1. 程式人生 > 其它 >String和StringBuffer和StringBuilder的區別

String和StringBuffer和StringBuilder的區別

String和StringBuffer和StringBuilder的區別

​ 簡要的說, String 型別和 StringBuffer 型別的主要效能區別其實在於 String 是不可變的物件, 因此在每次對 String 型別進行改變的時候其實都等同於生成了一個新的 String 物件,然後將指標指向新的 String 物件,這樣不僅效率低下,而且大量浪費有限的記憶體空間,所以經常改變內容的字串最好不要用 String 。因為每次生成物件都會對系統性能產生影響,特別當記憶體中無引用物件多了以後, JVM 的 GC 就會開始工作,那速度是一定會相當慢的。

String StringBuffer StringBuilder
String的值是不可變的,這就導致每次對String的操作都會生成新的String物件,不僅效率低下,而且浪費大量優先的記憶體空間 StringBuffer是可變類,和執行緒安全的字串操作類,任何對它指向的字串的操作都不會產生新的物件。每個StringBuffer物件都有一定的緩衝區容量,當字串大小沒有超過容量時,不會分配新的容量,當字串大小超過容量時,會自動增加容量 可變類,速度更快
不可變 可變 可變
執行緒安全 (所有公開方法都是 synchronized 修飾的) 執行緒不安全(沒有 StringBuilder 修飾)
多執行緒操作字串 單執行緒操作字串

​ 當對字串進行修改的時候,特別是字串物件經常改變的情況下,需要使用 StringBuffer 和 StringBuilder 類。

​ 和 String 類不同的是,StringBuffer 和 StringBuilder 類的物件能夠被多次的修改,並且不產生新的未使用物件

​ 由於 StringBuilder 相較於 StringBuffer 有速度優勢,所以多數情況下建議使用 StringBuilder 類。然而在應用程式要求執行緒安全的情況下,則必須使用 StringBuffer 類。

三者的繼承關係

三者的區別

小結:(1)如果要操作少量的資料用 String;

(2)多執行緒操作字串緩衝區下操作大量資料 StringBuffer;

(3)單執行緒操作字串緩衝區下操作大量資料 StringBuilder

StringBuffer與String的可變性問題。
我們先看看這兩個類的部分原始碼:

Java程式碼

//String   
public final class String  
{  
        private final char value[];  

         public String(String original) {  
              // 把原字串original切分成字元陣列並賦給value[];  
         }  
}  

//StringBuffer   
public final class StringBuffer extends AbstractStringBuilder  
{  
         char value[]; //繼承了父類AbstractStringBuilder中的value[]  

         public StringBuffer(String str) {  
                 super(str.length() + 16); //繼承父類的構造器,並建立一個大小為str.length()+16的value[]陣列  
                 append(str); //將str切分成字元序列並加入到value[]中  
        }  
}  

很顯然,String和StringBuffer中的value[]都用於儲存字元序列。但是,
(1) String中的是常量(final)陣列,只能被賦值一次。
比如:new String("abc")使得value[]={'a','b','c'}(檢視jdk String 就是這麼實現的),之後這個String物件中的value[]再也不能改變了。這也正是大家常說的,String是不可變的原因 。
注意:這個對初學者來說有個誤區,有人說String str1=new String("abc"); str1=new String("cba");不是改變了字串str1嗎?那麼你有必要先搞懂物件引用和物件本身的區別。這裡我簡單的說明一下,物件本身指的是存放在堆空間中的該物件的例項資料(非靜態非常量欄位)。而物件引用指的是堆中物件本身所存放的地址,一般方法區和Java棧中儲存的都是物件引用,而非物件本身的資料。

(2) StringBuffer中的value[]就是一個很普通的陣列,而且可以通過append()方法將新字串加入value[]末尾。這樣也就改變了value[]的內容和大小了。