java基礎鞏固系列(十):String、StringBuffer、StringBuilder的使用與比較
他們之間的主要區別:
String是字串常量,不能夠改變
StringBuffer是字串變數,可以改變,執行緒安全
StringBuilder是字串變數,可以改變,執行緒不安全(JDK1.5以後出現的)
一、為什麼說String是字串常量
首先,我們讓s1+=s2,然後s1的值變成了:Hello Worldpublic static void main(String[] args) { String s1 = "Hello "; String s2 = "World"; s1 += s2; System.out.println(s1); // Hello World s1 = s1.substring(6, 11); System.out.println(s1); //World }
看起來是String物件s1的值改變了,但是實際上是s1被賦值了一個新的引用,這個引用指向“Hello World”這個字串常量,而指向“Hello”的引用已經消失,這個時候“Hello”已經是屬於過時的物件,會被GC回收。
然後,我們又使用了s1.substring(6,11)函式,這個函式也是返回了一個新的引用,這時指向“Hello World”的引用也已經消失了,s1是一個新的引用。
而且,對於String物件的操作(包括replaceAll、replace、substring)都是返回了一個新的string物件。
二、StringBuilder物件詳解
API的解釋:
執行緒安全的可變字元序列。一個類似於 String 的字串緩衝區,但不能修改。雖然在任意時間點上它都包含某種特定的字元序列,但通過某些方法呼叫可以改變該序列的長度和內容。
可將字串緩衝區安全地用於多個執行緒。可以在必要時對這些方法進行同步,因此任意特定例項上的所有操作就好像是以序列順序發生的,該順序與所涉及的每個執行緒進行的方法呼叫順序一致。
在需要對字串執行重複修改的情況下,與建立新的 String 物件相關的系統開銷可能會非常昂貴。
public static void main(String[] args) { StringBuffer s1 = new StringBuffer("abcdf"); s1.append("ghi"); //output:abcdfghi s1.insert(4, "e"); //output:abcdefghi }
三、String物件拼接操作符“+”的特殊情況
至此,我們已經知道String物件是一個不可變的常量,那麼在String中進行 “+”拼接 操作的話,肯定也是要返回一個新的物件的,那麼肯定會影響效能。
但是,有特殊的情況:
public static void main(String[] args) {
//(1)
String s1 = "Hello ";
String s2 = "World!";
String s3 = s1 + s2;
System.out.println(s3); //output:Hello World!
//(2)
String s = "Hello "+"World!";
//(3)
StringBuffer sb = new StringBuffer("Hello ");
sb.append("World!");
}
在這三種情況中,按照速度排序:(2)>(3)>(1),這是JVM的一個特性,這時的String物件的拼接被解釋成StringBuffer物件的拼接:
String s = "Hello "+"World!"; 被認為成 String s = "Hello World!";
四、String、StringBuffer、StringBuilder之間的區別
String是不可變的常量
StringBuffer與StringBuilder都是可以改變的變數,其中StringBuffer是執行緒安全的,保證同步;StringBuilder不是執行緒安全的,不能保證同步。
StringBuilder類被設計用作 StringBuffer 的一個簡易替換,用在字串緩衝區被單個執行緒使用的時候(這種情況很普遍)。如果可能,建議優先採用該類,因為在大多數實現中,它比 StringBuffer 要快。兩者的方法基本相同。