应根据场景选择字符串拼接方式:编译期常量用+,少量运行期变量拼接用+,循环内或高频拼接必须用stringbuilder,并预估容量以提升性能。

加号(+)和 StringBuilder 不是“谁更快”的简单选择,而是“在什么场景下该用哪个”的工程判断。关键不在语法本身,而在拼接发生的时机、次数和上下文。
编译期常量拼接:+ 更优且更简洁
当所有参与拼接的都是字符串字面量或 final 常量(如 "a" + "b" + "c" 或 final String PREFIX = "v1"; PREFIX + "/api"),Java 编译器会在编译阶段直接合并为一个字符串常量。运行时零对象创建、零方法调用,性能最优,代码也最直观。
- 不要为了“统一风格”把这种写法硬改成 StringBuilder —— 反而增加冗余字节码
- IDE 或 javap -c 查看字节码,你会看到 ldc 指令加载常量,没有 new StringBuilder
少量运行期变量拼接:+ 完全可用,现代 JVM 已优化
拼接项在 2~4 个、不含循环、变量值在方法内确定(如 "User " + name + " logged in at " + LocalDateTime.now()),JDK 9+ 的 StringConcatFactory 会生成高效字节码,底层可能复用 StringBuilder 或更轻量实现。
- 性能与手写 StringBuilder 基本无差异,实测差距通常在纳秒级
- 此时优先选 +:可读性高、维护成本低、不易出错
- concat() 仅适合两个非空字符串,且不处理 null,适用面窄,一般不用
循环内或高频拼接:必须用 StringBuilder
这是性能分水岭。每次 result += s 都等价于 new StringBuilder().append(result).append(s).toString(),旧内容被反复复制,时间复杂度接近 O(n²),内存压力陡增。
- 正确做法:声明一次 StringBuilder,循环中只 append,最后 toString()
- 预估总长度(如拼接 500 个平均 12 字符的 ID),初始化时指定容量:new StringBuilder(500 * 12)
- 避免 sb.append("") 这类无效调用,不贡献内容还多一次方法分派
其他实用建议
集合拼接优先用 String.join(",", list),格式化优先用 String.format 或 Text Blocks(JDK 15+),它们内部已做针对性优化;多线程共享拼接器极少见,真需要时才考虑 StringBuffer,但更推荐重构为局部变量 + StringBuilder。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











