使用 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) 重置。
- 循环外创建:
StringBuilder sb = new StringBuilder(128); - 循环内重用:
sb.setLength(0); sb.append(...);—— 比new快,且不改变底层数组引用 - 注意线程安全:
StringBuilder非线程安全,多线程必须各自持有实例或改用StringBuffer(但性能略低)
慎用 toString() 的时机,避免过早固化
toString() 会创建不可变的 String 对象,并复制当前内容。若后续还需追加,应延后调用。
- 错误示例:
String s = sb.toString(); sb.append("extra");—— 前面的s已触发一次复制,后面又继续操作原 sb,逻辑割裂 - 正确做法:所有拼接完成后再调用
toString(),或用sb.length()和sb.charAt()做条件判断而不转字符串 - 若只需部分结果,可用
sb.subSequence(start, end).toString(),但注意它仍会新建 String
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











