结论:循环内反复拼接(如日志、SQL、HTML生成)必须显式用StringBuilder;编译期可确定的少量拼接(1–2次)用“+”更简洁高效。
直接说结论:用拼接 3 次以上字符串时,性能明显优于或;但若只有 1–2 次拼接,编译器常自动优化为,手动写反而多余。
什么时候必须显式用
?
典型场景是循环内反复拼接(比如日志组装、SQL 构建、HTML 片段生成),此时每次用
都会创建新
对象,触发频繁 GC。
循环次数 ≥ 5,且每次拼接内容长度 > 10 字符 → 强烈建议用
拼接逻辑跨多个方法调用(如递归、回调)→ 编译器无法优化,必须手动传入
实例
需要控制容量避免扩容(如已知最终长度约 2KB)→ 可用
预分配
的参数类型和隐式转换陷阱
重载多,但不是所有类型都“安全”。最常见问题是误传
或未处理的
:
传
→ 实际追加字符串
,不是空指针异常(容易漏掉)
传自定义对象(没重写
)→ 拼出类似
,而非业务期望值
数字类型(
/
)直接 append 是高效的,但
会触发装箱+字符串格式化,若需精度控制,改用
后再 append
线程安全吗?能不能共享实例?
是非线程安全的 —— 它没有同步开销,所以快;但也意味着不能在多个线程间共享同一个实例。
在单线程方法内局部创建(推荐):
在线程池任务中复用?可以,但必须确保该实例不被其他线程访问,例如通过
管理
误用
全局共享 → 出现乱序、丢失字符、甚至
(扩容时内部数组被并发修改)
真正难的是预估初始容量和判断是否值得提前抽象——很多人在只拼 2 个字符串时硬套
,反而增加代码噪声。记住:优化要落在热路径上,而不是语法洁癖里。
StringBuilder+String.concat()StringBuilderStringBuilder+StringStringBuilderStringBuildernew StringBuilder(2048)append()StringBuilder.append()nullObjectnull"null"toString()"com.example.User@1a2b3c"intlongdoubleString.format()StringBuilderStringBuilder sb = new StringBuilder();ThreadLocalstatic StringBuilderArrayIndexOutOfBoundsExceptionStringBuilder