String StringBuffer 和 StringBuilder 的區(qū)別? String 為什么是不可變的?
可變性
簡單的來說:String 類中使用 final 關(guān)鍵字修飾字符數(shù)組來保存字符串,private final char value[]
烈钞,所以 String 對象是不可變的藕坯。而StringBuilder 與 StringBuffer 都繼承自 AbstractStringBuilder 類师逸,在 AbstractStringBuilder 中也是使用字符數(shù)組保存字符串char[]value
但是沒有用 final 關(guān)鍵字修飾,所以這兩種對象都是可變的瓷叫。
StringBuilder 與 StringBuffer 的構(gòu)造方法都是調(diào)用父類構(gòu)造方法也就是 AbstractStringBuilder 實現(xiàn)的拴驮,大家可以自行查閱源碼惑灵。
AbstractStringBuilder.java
abstract class AbstractStringBuilder implements Appendable, CharSequence {
char[] value;
int count;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
線程安全性
String 中的對象是不可變的,也就可以理解為常量手报,線程安全蚯舱。AbstractStringBuilder 是 StringBuilder 與 StringBuffer 的公共父類,定義了一些字符串的基本操作掩蛤,如 expandCapacity枉昏、append、insert揍鸟、indexOf 等公共方法兄裂。StringBuffer 對方法加了同步鎖或者對調(diào)用的方法加了同步鎖,所以是線程安全的阳藻。StringBuilder 并沒有對方法進(jìn)行加同步鎖晰奖,所以是非線程安全的。
性能
每次對 String 類型進(jìn)行改變的時候腥泥,都會生成一個新的 String 對象匾南,然后將指針指向新的 String 對象。StringBuffer 每次都會對 StringBuffer 對象本身進(jìn)行操作蛔外,而不是生成新的對象并改變對象引用蛆楞。相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升溯乒,但卻要冒多線程不安全的風(fēng)險。
對于三者使用的總結(jié):
- 操作少量的數(shù)據(jù): 適用String
- 單線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù): 適用StringBuilder
- 多線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù): 適用StringBuffer