- 可變性:
- String 類中使用 final 關鍵字字符數(shù)組保存字符串够颠,
private final char value[]
熙侍,所以 String 對象是不可變的。 - 而 StringBuilder 和 StringBuffer 都繼承自 AbstractStringBuilder 類履磨,在AbstractStringBuilder 中也是使用字符數(shù)組保存字符串
char[]value
但是沒有用 final 關鍵字修飾蛉抓,所以這兩種對象都是可變的。
StringBuilder 和 StringBuffer 的構造方法都是調(diào)用父類的構造方法也就是 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 并沒有對方法進行加同步鎖,所以是非線程安全的妖胀。
- 性能:
- 每次對 String 類型進行改變的時候芥颈,都會生成一個新的 String 對象惠勒,然后指針指向新的 String 對象。
- StringBuffer 每次都會對 StringBuffer 對象本身進行操作爬坑,而不是生成新的對象并改變對象引用纠屋。相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒出線程不安全的風險盾计。
對于三者使用的總結(jié):
- 操作少量的數(shù)據(jù) = String
- 單線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù) = StringBuilder
- 多線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù) = StringBuffer
既然提到了final
售担,總結(jié)下final
:
final 關鍵字主要用在三個方面:變量、方法署辉、類
- 對于一個 final 變量族铆,如果是基本數(shù)據(jù)類型的變量,則其數(shù)值一旦在初始化后便不能更改哭尝;如果是引用類型變量哥攘,則對其初始化之后便不能再讓其指向另一個對象。
- 當用 final 修飾一個類時材鹦,表明這個類不能被繼承逝淹。final 類中的所有成員方法都會被隱式地指定為 final 方法。
- 使用 final 方法的原因有兩個:
- 把方法鎖定侠姑,以防任何繼承類修改它的定義;
- 效率箩做。在早期的 Java 實現(xiàn)版本中莽红,會將 final 方法轉(zhuǎn)為內(nèi)嵌調(diào)用。但是如果方法過于龐大邦邦,可能看不到內(nèi)嵌調(diào)用帶來的任何性能提升(現(xiàn)在的 Java 版本已經(jīng)不需要使用 final 關鍵字進行這些優(yōu)化了)安吁。類中所有的 private 方法都隱式地指定為 final。