stringbuilder 替代 string += 是 java 中见效最快、改动最小的性能优化,关键在于避免 string 不可变性导致的对象爆炸;需循环外初始化、预设容量、链式 append、合理复用,且仅在高频运行时路径(如循环拼接)中使用。

直接用 StringBuilder 替代 String += 是 Java 中见效最快、改动最小的性能优化之一。它不改变业务逻辑,却能把循环拼接从秒级压到毫秒级——关键在于绕开 String 不可变性带来的对象爆炸。
循环外初始化,循环内只 append
错误写法会在每次迭代中新建 StringBuilder 和 String 对象,产生大量临时对象:
- ❌
String s = ""; for (String item : list) { s += item; } - ✅ 正确做法:循环前创建一次,循环中只调用
append(),最后统一toString() - 示例:
StringBuilder sb = new StringBuilder(); for (String s : list) { sb.append(s).append(","); } String result = sb.toString();
预设合理初始容量,减少扩容开销
StringBuilder 底层是 char 数组,默认容量仅 16。超出后按 旧容量 × 2 + 2 扩容,每次都要复制整个数组——这是隐藏性能杀手。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 拼接 500 条日志,每条平均 60 字符 + 换行符:预估长度 ≈ 500 × 61 = 30500 →
new StringBuilder(32000) - 不确定长度但数据量大(如日志缓冲区):宁可高估(如 4096 或 8192),也别让扩容发生两次以上
- 避免用
ensureCapacity()补救——它只扩不缩,还多一次方法调用
坚持链式 append,禁用混用 + 和 toString()
append() 返回自身,支持连续调用,且自动处理类型转换(int、boolean、null 等):
- ✅
sb.append("id:").append(id).append(", name:").append(name) - ❌ 避免
sb.append("a" + "b")——编译器会先生成临时 StringBuilder,白忙一场 - ❌ 禁止在循环里反复调用
toString():每次都会复制整个数组,开销是 O(n) - ⚠️
append(null)在 JDK 8+ 直接抛NullPointerException;需提前判空或用Objects.toString(x, "")
复用实例与线程安全边界
StringBuilder 本身非线程安全,但复用得当能显著降低 GC 压力:
- 单线程方法内:用
sb.setLength(0)清空比新建更快,适合多次拼接场景 - 线程池任务中:配合
ThreadLocal<stringbuilder></stringbuilder>隔离,既复用又安全 - ❌ 绝对禁止 static 共享或跨线程传递同一实例——可能丢字符、乱序,甚至崩溃
- 真需多线程共享?改用
StringBuffer,但注意同步开销约增加 50%~100%
不是所有拼接都值得上 StringBuilder。纯字面量("a" + "b")、≤2 次变量拼接、或简单分隔(String.join(",", list))时,JDK 已自动优化,手动写反而冗余。真正该发力的地方,是循环、日志、SQL/JSON 构建这类高频运行时路径。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










