高效使用 StringBuilder 的核心是复用实例、避免隐式装箱与临时 String 创建、预设合理容量;错误做法是循环内新建,正确做法是循环外初始化并按需 clear() 或 setLength(0),优先调用基本类型重载方法,合理预估容量减少扩容。

在 Java 中,用 StringBuilder.append() 在循环内拼接多个变量时,关键不是“调用多少次 append”,而是避免隐式装箱、重复创建对象、以及不必要的字符串转换。高效的核心在于:**复用同一个 StringBuilder 实例、按需调用 append、减少中间 String 对象生成**。
避免在循环内反复 new StringBuilder
每次循环都新建 StringBuilder,会抵消掉所有性能优势,还增加 GC 压力。
❌ 错误写法:
for (String item : list) {
StringBuilder sb = new StringBuilder(); // 每次都新建!
sb.append("id=").append(item.getId())
.append(", name=").append(item.getName());
result.add(sb.toString());
}
✅ 正确做法:提前声明,循环外初始化(或复用已有实例):
立即学习“Java免费学习笔记(深入)”;
- 若只需单次拼接结果,循环前 new 一次,循环中 clear() 或 setLength(0)
- 若每次拼接独立结果(如构建多条日志),可考虑预估容量 + 复用对象池(中小项目通常无需)
按类型直接 append,绕过 toString() 和自动装箱
对基本类型(int、long、boolean 等)和包装类,StringBuilder.append() 提供了重载方法,直接写入字符序列,不经过 String 转换。
推荐写法(高效):
sb.append("user:")
.append(userId) // int → 直接写入数字字符,无 Integer.toString()
.append(", active=")
.append(isActive) // boolean → 写入 "true"/"false"
.append(", score=")
.append(score); // double → 高效转字符串(比 String.valueOf 更轻量)
避免写法:sb.append("" + userId) 或 sb.append(String.valueOf(userId)) —— 多一次临时 String 创建。
合理预设初始容量,减少数组扩容
StringBuilder 底层是 char[],扩容涉及数组复制。若能预估最终长度,构造时指定容量,可显著减少 resize 次数。
例如拼接格式为 "[id:123,name:abc,age:25]",每个字段平均长度已知:
- 固定字符数(如 "[id:", ",name:", ",age:", "]")共约 18 字符
- 假设 id 平均 5 位、name 平均 10 字、age 平均 2 位 → 动态部分约 17 字
- 预留 40 字符足够:
new StringBuilder(40)
不确定时,宁可略大勿小;但也不必过度预估(如设 1024 去拼接 20 字符的字符串)。
链式调用与分段拼接的取舍
连续 append 可以链式调用(返回 this),代码简洁且无额外开销:
sb.append('[')
.append("id:").append(id)
.append(",name:").append(name)
.append(']');
但若逻辑分支多(如某些字段可能为空需跳过),强行链式反而难读。此时拆成清晰的条件块更稳妥:
sb.append('[');
if (id != null) sb.append("id:").append(id).append(',');
if (name != null) sb.append("name:").append(name);
sb.append(']');
性能几乎无差异,可读性和可维护性更重要。


















