1. 概述
本文将深入探讨 Java 中 StringBuilder
和 StringBuffer
的核心异同点。简单来说,StringBuilder
是 Java 1.5 引入的 StringBuffer
替代品,两者在设计理念上存在关键差异。
2. 相似之处
StringBuilder
和 StringBuffer
都创建可变字符序列对象。我们通过对比不可变的 String
类来理解其工作原理:
String immutable = "abc";
immutable = immutable + "def"; // ❌ 实际创建了新对象
看似修改了原对象,实则因 String
的不可变性,每次操作都会生成新实例。而使用 StringBuffer
或 StringBuilder
时:
StringBuffer sb = new StringBuffer("abc");
sb.append("def"); // ✅ 直接修改原对象内容
通过调用 append()
方法直接修改原对象,无需创建新实例,体现了两者的可变性。
3. 核心差异
StringBuffer
是同步的线程安全实现,而 StringBuilder
兼容其 API 但不保证同步。由于缺少同步开销,StringBuilder
性能更优,适用于单线程场景。
3.1 性能对比
在小规模迭代中差异可忽略,但通过 JMH 微基准测试(1k 次迭代):
@State(Scope.Benchmark)
public static class MyState {
int iterations = 1000;
String initial = "abc";
String suffix = "def";
}
@Benchmark
public StringBuffer benchmarkStringBuffer(MyState state) {
StringBuffer stringBuffer = new StringBuffer(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuffer.append(state.suffix);
}
return stringBuffer;
}
@Benchmark
public StringBuilder benchmarkStringBuilder(MyState state) {
StringBuilder stringBuilder = new StringBuilder(state.initial);
for (int i = 0; i < state.iterations; i++) {
stringBuilder.append(state.suffix);
}
return stringBuilder;
}
测试结果(吞吐量模式,分数越高越好):
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 86169.834 ± 972.477 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 91076.952 ± 2818.028 ops/s
当迭代增至 1M 次时差异更明显:
Benchmark Mode Cnt Score Error Units
StringBufferStringBuilder.benchmarkStringBuffer thrpt 200 77.178 ± 0.898 ops/s
StringBufferStringBuilder.benchmarkStringBuilder thrpt 200 85.769 ± 1.966 ops/s
⚠️ 注意:微基准测试结果需谨慎解读,实际应用性能需结合具体场景分析。
4. 实践建议
StringBuffer
因线程安全设计性能较低,StringBuilder
在单线程场景更高效。但需注意:
- ✅ 单线程环境优先使用
StringBuilder
- ✅ 多线程共享数据时必须用
StringBuffer
- ⚠️ 性能提升可能微小,替换前建议做实际性能分析
- ❌ 避免在低频操作中过度优化
代码示例可在 GitHub 获取完整实现。