| 特性 | StringBuffer | StringBuilder |
|---|---|---|
| 引入版本 | JDK 1.0 | JDK 5.0 |
| 線程安全 | 所有公共方法 synchronized | 非線程安全 |
| 效能 | 同步開銷,較慢 | 無同步,單執行緒下顯著更快 |
| API 相容性 | 完全相同 | 完全相同 |
| 繼承關係 | AbstractStringBuilder | AbstractStringBuilder |
StringBuffer 早期為了線程安全,所有方法加 synchronized。但實際使用場景中,字串建構器多為 方法區域變數,不跨執行緒共享,同步完全多餘。JDK 5 引入 StringBuilder 移除同步,提供 2-3 倍效能提升。
// 方法內部區域變數 → 單執行緒 → 用 StringBuilder
public String toString() {
return new StringBuilder()
.append("User{id=").append(id)
.append(", name='").append(name).append('\'')
.append(", email='").append(email).append('\'')
.append('}').toString();
}
// 共享緩衝區(罕見) → 需線程安全 → 用 StringBuffer
// 或更佳:ThreadLocal / 並發容器
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class StringBuilderBenchmark {
@Benchmark
public void stringBuffer() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 100; i++) sb.append("test");
}
@Benchmark
public void stringBuilder() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) sb.append("test");
}
}
// 典型結果:StringBuilder 約快 2-3 倍
String 為 final class,內部 final char[] value(JDK 9+ 為 byte[] + coder)。每次拼接 s += "x" 都會建立新物件、複製陣列,循環中會產生大量暫存物件 → GC 壓力。StringBuilder 內部維護可擴充陣列,只在 toString() 時建立最終 String。
new StringBuilder(estimatedSize) 減少擴容複製。StringBuilder 是 StringBuffer 的非同步替代品,針對單執行緒場景優化。理解「區域變數不共享」這一事實,是選擇正確工具的關鍵。現代代碼中,StringBuilder 應為首選。