StringBuilder通过复用内部非final char[]缓冲区实现高效字符串操作,支持setLength(0)清空、预估容量避免扩容,配合ThreadLocal可线程安全复用,性能优于StringBuffer。

StringBuilder 通过复用同一实例的内部 char[] 缓冲区,避免频繁分配新数组,从而显著降低 GC 压力。它的核心机制不是“自动回收”,而是“可控复用”——关键在于你主动管理生命周期和容量。
复用的前提:理解内部缓冲区的可变性
StringBuilder 继承自 AbstractStringBuilder,底层使用非 final 的 char[] value 数组存储字符,且提供 setLength(0)、delete(0, length()) 等方法清空内容但不释放数组。只要不触发扩容,后续 append 操作就直接复用原有内存空间。
正确复用的典型做法
- 在确定作用域内(如一个方法块或循环体)声明并复用同一个 StringBuilder 实例,而不是每次 new
- 每次使用前调用 setLength(0) 彻底清空逻辑长度(比 delete(0, length()) 更轻量,不涉及数组复制)
- 初始化时预估容量(如 new StringBuilder(1024)),避免多次扩容导致旧数组被丢弃
- 避免将其作为类成员长期持有——这会延长引用生命周期,反而阻碍 GC,应限定在局部作用域内
配合 ThreadLocal 实现线程级复用
在高并发场景中,可结合 ThreadLocal 避免锁竞争,同时防止跨线程共享带来的安全问题:
private static final ThreadLocal
立即学习“Java免费学习笔记(深入)”;
每次从 TL 获取后,先 setLength(0),再 append 内容,用完不手动清理(ThreadLocal 自动关联线程生命周期)。
为什么不用 StringBuffer?
StringBuffer 所有 public 方法都加了 synchronized,虽然线程安全,但同步开销在单线程场景下纯属冗余。StringBuilder 在绝大多数业务逻辑(如 Controller 层拼接响应、DAO 层构造 SQL)中是更轻量、更高效的选择——复用效果相同,性能更高。


















