問十:String StringBuffer StringBuilder的區別是什麼?

直接上API doc

java.lang.String

The String class represents character strings. All string literals(字面量) in Java programs, such as "abc", are implemented as instances of this class.(所以字符串常量池中存的應該是對象吧?挖坑,後面填)

Strings are constant; their values cannot be changed after they are created. String buffers support mutable (可變的)strings. Because String objects are immutable they can be shared.

The Java language provides special support for the string concatenation operator ( + )【Java語言爲字符串連接操作符提供了特殊的支持。, and for conversion of other objects to strings. String concatenation is implemented through the StringBuilder(or StringBuffer) class and its append method. String conversions are implemented through the method toString, defined by Object and inherited by all classes in Java. 

A String represents a string in the UTF-16 format in which supplementary characters are represented by surrogate pairs .

java.lang.StringBuffer

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.

String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.

java.lang.StringBuilder

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

 

回答

String 是 Java 語言非常基礎和重要的類,提供了構造和管理字符串的各種基本邏輯。它是典型的 Immutable 類被聲明成爲 final class,所有屬性也都是 final 的。也由於它的不可變性,類似拼接、裁剪字符串等動作,都會產生新的 String 對象(中間對象是StringBuffer,然後調用它的toString方法,new一個String對象出來)。由於字符串操作的普遍性,所以相關操作的效率往往對應用性能有明顯影響。

 

StringBuffer 是爲解決上面提到拼接產生太多中間對象的問題而提供的一個類,它是 Java 1.5中新增的,我們可以用 append 或者 add 方法,把字符串添加到已有序列的末尾或者指定位置。StringBuffer 本質是一個線程安全的可修改字符序列,它保證了線程安全(因爲對類中的操作方法【構造函數沒有】加了synchronized關鍵字),也隨之帶來了額外的性能開銷,所以除非有線程安全的需要,不然還是推薦使用它的後繼者,也就是StringBuilder。

 

StringBuilder 在能力上和 StringBuffer 沒有本質區別,但是它去掉了線程安全的部分,有效減小了開銷,是絕大部分情況下進行字符串拼接的首選。

 

在JDK1.7之後引入了偏向鎖,因此StringBuffer和StringBuilder在單線程執行的環境下性能上是差不多的

附加:找一找內部怎麼存的,然後不同版本的jdk底層實現的不同

 

附加:StringBuffer和StringBuilder是如何維護它內部的動態char[]的?

    String 類不可變,內部維護的char[] 數組長度不可變,爲final修飾,String類也是final修飾,不存在擴容。字符串拼接,截取,都會生成一個新的對象。頻繁操作字符串效率低下,因爲每次都會生成新的對象。

    StringBuilder 類內部維護可變長度char[] , 初始化數組容量爲16,存在擴容, 其append拼接字符串方法內部調用System的native方法,進行數組的拷貝,不會重新生成新的StringBuilder對象。非線程安全的字符串操作類, 其每次調用 toString方法而重新生成的String對象,不會共享StringBuilder對象內部的char[],會進行一次char[]的copy操作。

    StringBuffer 類內部維護可變長度char[], 基本上與StringBuilder一致,但其爲線程安全的字符串操作類,大部分方法都採用了Synchronized關鍵字修改,以此來實現在多線程下的操作字符串的安全性。其toString方法而重新生成的String對象,會共享StringBuffer對象中的toStringCache屬性(char[]),但是每次的StringBuffer對象修改,都會置null該屬性值。

    源碼解析哪天心情好再添加:)可以看零碎小知識的網頁剪切。

 

附加:String的+操作在編譯器裏是如何優化的?

String str = "a" + "b";  優化爲ab

String str = "a" + (1 + 2);  優化爲a3

注:String相加還可以使用concat

        

String s = "b";  

String str = "a" + s;  

這個是創建一個StringBuilder對象,調用append方法進行添加,調用toString重新生成String對象

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章