性能排序为StringBuilder > StringBuffer > String:StringBuilder单线程最快,无同步开销;StringBuffer线程安全但有锁竞争;String不可变,循环拼接产生大量临时对象,应避免。

性能排序很明确:StringBuilder > StringBuffer > String(在频繁拼接场景下)。
StringBuilder 性能最优
单线程环境下,StringBuilder 是字符串拼接的首选。它继承自 AbstractStringBuilder,底层用可变 char[](JDK8)或 byte[](JDK9+),所有 append、insert 等操作直接修改数组内容,不加锁、无同步开销。实测中,10 万次拼接比 StringBuffer 快约 10–20%。
- 适合循环拼接、日志组装、JSON 字段构建等单线程高频操作
- 初始容量默认为 16;若预估长度较大(如拼接 5000 字符),建议显式指定 capacity,避免多次扩容(扩容公式:newCapacity = oldCapacity × 2 + 2)
- 注意:不能在多线程共享实例中使用,否则可能产生数据错乱
StringBuffer 次之,但线程安全
功能与 StringBuilder 几乎完全一致,区别仅在于所有 public 修改方法(如 append、delete)都加了 synchronized。这保证了多线程并发调用时的数据一致性,但也引入了锁竞争和上下文切换成本。
- 适用于后台服务中多个线程共用同一缓冲区拼接日志、生成 XML/SQL 的场景
- 如果实际并发度低(比如只有 2–3 个线程偶尔写入),性能差距不明显;高并发下吞吐会明显下降
- 不要为了“保险”而在单线程代码里默认用 StringBuffer——纯属性能浪费
String 拼接性能最差(尤其循环中)
String 不可变,每次 += 或 concat 都会新建对象:先创建 StringBuilder → 执行 append → 调用 toString() 生成新 String → 原对象等待 GC。循环 10000 次可能产生上万个临时对象,触发多次 Young GC,响应时间陡增。
立即学习“Java免费学习笔记(深入)”;
- 仅推荐用于字面量拼接(如 "a" + "b" + "c"),编译期就优化为常量池中的单一字符串
- 少量、非循环拼接(如两个变量拼一次)影响不大,JVM 会自动用 StringBuilder 优化
- 绝对避免在 for/while 循环内用 String += ……,这是典型性能陷阱
额外影响因素:Java 版本与底层优化
JDK9+ 对 String 底层做了内存优化(byte[] + coder),Latin-1 编码字符串内存减半;JDK17 引入 invokedynamic 指令优化字符串拼接,但只对编译期可确定的静态拼接生效,对运行时动态拼接无帮助。所以 StringBuilder/StringBuffer 的优势在任何现代 JDK 中依然成立。



















