天天看點

Java中String,StringBuilder和StringBuffer的差別

這三個類的主要差別在兩個方面:運算速度(運算性能或執行效率)和線程安全性。

String StringBuilder StringBuffer
不可變 可變 可變
線程不安全 線程安全

1、運算速度比較(通常情況下):StringBuilder > StringBuffer > String

String是final類不能被繼承且為字元串常量,而StringBuilder和StringBuffer均為字元串變量。String對象一旦建立便不可更改,而後兩者是可更改的,它們隻能通過構造函數來建立對象,且對象被建立以後将在記憶體中配置設定記憶體空間,并初始儲存一個null,通過append方法向StringBuffer和StringBuilder中指派。

請看如下示例代碼:

String str = "abc";
System.out.println(str);
str = str + "de";
System.out.println(str);
           

上述代碼先建立一個String對象str,并指派abc給str,然後運作到第三行,JVM會再建立一個新的str對象,并将原有str的值和de加起來再指派給新的str。而第一個建立的str對象被JVM的垃圾回收機制(GC)回收掉。是以str實際上并沒有被更改,即String對象一旦建立就不可更改。是以Java中對String對象進行的操作實際上是一個不斷建立并回收對象的過程,是以在運作速度上很慢。

而StringBuilder和StringBuffer的對象是變量,對變量的操作是直接對該對象就行更改,是以不會進行反複的建立和回收。是以在運作速度上比較快。

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

上述代碼中String的操作速度反而要比StringBuilder快,這是因為在JVM眼裡,第1行的代碼操作和下列代碼是完全一樣的,是以很快。

但如下的代碼寫法形式速度會很慢,JVM會不斷地建立和回收對象來進行操作。

String str1 = "abc";
String str2 = "de";
String str = str1 + str2;
           

2、線程安全性

StringBuilder(非線程安全的)

而StringBuilder的方法沒有該關鍵字修飾,是以不能保證線程安全性。是JDK1.5新增的,該類提供一個與StringBuffer相容的 API,但不能保證同步,是以在性能上較高。該類被設計用作 StringBuffer 的一個簡易替換,用在字元串緩沖區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先采用該類,因為在大多數實作中,它比 StringBuffer 要快。兩者的方法基本相同。

StringBuffer(線程安全的)

StringBuffer中大部分方法由synchronized關鍵字修飾,在必要時可對方法進行同步,是以任意特定執行個體上的所有操作就好像是以串行順序發生的,該順序與所涉及的每個線程進行的方法調用順序一緻,是以是線程安全的。類似于 String 的字元串緩沖區,但不能修改。雖然在任意時間點上它都包含某種特定的字元序列,但通過某些方法調用可以改變該序列的長度和内容。StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的資料。每個方法都能有效地将給定的資料轉換成字元串,然後将該字元串的字元追加或插入到字元串緩沖區中。append 方法始終将這些字元添加到緩沖區的末端;而 insert 方法則在指定的點添加字元。

3、總結

String:适用于少量的字元串操作。

StringBuilder:适用于單線程下在字元串緩沖區進行大量操作。

StringBuffer:适用于多線程下在字元串緩沖區進行大量操作。

繼續閱讀