Java中的字符串 String, StringBuffer和StringBuilder

網上關於這方面的爆料很多,這裏我就針對我自己的理解敘述一下,就當筆記,如果哪裏有理解錯誤,請拋磚。

String類型,類似於常量,對它對象的每一個此操作相當於拋棄了原來的String對象,生成一個新的String對象,讓對象指向新String對象地址,例如:

String str1 = new String("abc");//新建一個str對象,比如爲其分配地址:12345,即str指向的地址是12345

String str2 = new String("def");

str1 = str1 + str2;

解析:這裏其實又新建了一個String對象其值爲abcdef,那麼此時str指向的地址不再是12345,而是其他地址值,也就是說存儲有“abc”的地址空間已經被捨棄,成爲廢棄的地址空間,縱然JAVA有完美的垃圾回收機制,程序員不用擔心內存溢出,但是當有很多廢棄地址空間時,調用GC來回收,仍然需耗費系統很多資源,從而減低系統性能。

StringBuffer的情形:

StringBuffer str1= new StringBuffer("abc");//假設此時地址認爲:12345

String str2 = "def";

str1.append(str2);//此時str1指向的地址空間仍爲12345

之所以會出現上面情形,是由StringBuffer的內部實現機制決定的,StringBuffer預先預留一部分地址空間以備擴充(一般是16個字符的預留空間),只有當需要的地址空間超過預留的地址空間時,纔會創建一個新對象,這點和String對象一樣的。

下面還有一個特殊的例子,

String str = " I am " + "a" + " student.";

StringBuffer strB = new StringBuffer("I am ").append("a").append(" student.");

估計大家都認爲這個例子跟大多數例子一樣,內存中會有I am a student的一個副本,其實是錯了,這時JVM會把" I am " + "a" + " student."看作是" I am a student."一個整體,也就是

String str = " I am " + "a" + " student.";

就像當於

String str = " I am a student.";

所以效率會比用StringBuffer要高。

從JDK 5.0開始添加了一個新字符串類型StringBuilder,這點是相對於StringBuffer和String緩衝區的單線程安全而言的,這裏所謂的單線程安全是指StringBuffer和String的緩衝區在一個時刻只能由一個線程訪問,也就是說,當有多個線程訪問,只能一個線程操縱,其他線程等待,這樣會降低多線程的性能。又因爲StringBuilder不需要處理同步,而節省資源,所以在多線程之間沒有寫數據同步時,推薦使用StringBuilder,而當有數據同步時仍然使用StringBuffer。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章