使用 StringBuilder.append() 比 + 拼接更高效,预估容量可避免扩容,链式调用更简洁,需处理 null,循环中复用实例并 setLength(0),toString() 应延后调用。
直接用 stringbuilder.append() 逐个追加变量,比用 + 拼接字符串更高效,能显著减少临时 string 对象的创建,从而降低 gc 压力。
预估容量,避免扩容开销
每次 StringBuilder 内部数组满时会触发扩容(通常是翻倍),产生额外对象和内存拷贝。提前设置合理初始容量可规避这个问题。
- 粗略估算拼接后总长度:把各变量的
toString().length()加上分隔符长度(如逗号、空格) - 构造时传入预估容量:
new StringBuilder(estimatedLength) - 例如拼接
name="Alice"、age=28、city="Beijing",预估长度 ≈ 5 + 2 + 7 + 2(两个逗号) = 16 →new StringBuilder(20)更稳妥
连续调用 append(),不拆分成多个语句
append() 返回 this,支持链式调用。保持单次构建逻辑连贯,既简洁又避免中间变量干扰 JIT 优化。
- 推荐写法:
sb.append(name).append(',').append(age).append(',').append(city); - 避免写成多条独立语句(虽无错,但冗余且易漏掉某次 append)
- 对 null 值需主动处理,否则
append(null)会写入字符串 "null";可用Objects.toString(obj, "")或三元判断
复用 StringBuilder 实例,尤其在循环或高频场景中
在方法内新建 StringBuilder 是安全的,但在循环体中反复 new 仍会增加分配频率。可考虑复用实例并配合 setLength(0) 重置。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 循环外创建:
StringBuilder sb = new StringBuilder(128); - 循环内重用:
sb.setLength(0); sb.append(...);—— 比new快,且不改变底层数组引用 - 注意线程安全:
StringBuilder非线程安全,多线程必须各自持有实例或改用StringBuffer(但性能略低)
慎用 toString() 的时机,避免过早固化
toString() 会创建不可变的 String 对象,并复制当前内容。若后续还需追加,应延后调用。
立即学习“Java免费学习笔记(深入)”;
- 错误示例:
String s = sb.toString(); sb.append("extra");—— 前面的s已触发一次复制,后面又继续操作原 sb,逻辑割裂 - 正确做法:所有拼接完成后再调用
toString(),或用sb.length()和sb.charAt()做条件判断而不转字符串 - 若只需部分结果,可用
sb.subSequence(start, end).toString(),但注意它仍会新建 String

















