选string:内容不变,如配置项、常量;选stringbuilder:单线程频繁修改,性能高;选stringbuffer:多线程共享修改且需同步。匹配场景才高效。

选对字符串类型,关键看三点:内容变不变、线程多不多、性能要求高不高。不是越新越好,也不是越安全越优,而是匹配场景才真正高效。
字符串内容基本不变 → 用 String
String 是不可变的,适合做“定稿”用。比如配置项、错误码、SQL 模板、HTTP 响应头这些写死或极少改动的内容。它天然线程安全,还能享受字符串常量池优化——相同字面值只存一份,节省内存。
- 定义常量直接用双引号:
"user.not.found",别写new String("...") - 少量拼接(比如日志中加个 ID)可以用
+,JVM 会自动优化成 StringBuilder - 避免在循环里反复用
+=,哪怕只有几十次,也会触发大量对象创建和 GC
单线程下频繁修改 → 优先选 StringBuilder
日常业务代码里,比如组装 JSON、生成 SQL、拼接路径、构建 HTML 片段,绝大多数都在单线程中完成。StringBuilder 可变、不加锁、扩容策略合理,性能比 StringBuffer 高 10%–15%。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 初始化时预估容量,减少数组扩容次数:
new StringBuilder(256) - 常用操作就几个:
append()、insert()、delete()、toString() - 方法链式调用很自然:
sb.append("id=").append(id).append("&name=").append(name)
多线程共享修改 → 必须用 StringBuffer
只有当你明确需要多个线程共用同一个字符串缓冲区,并且不做额外同步时,才考虑 StringBuffer。它的每个 public 方法都加了 synchronized,能保证 append、reverse 等操作的原子性。
- 典型场景:全局日志缓冲器、共享的统计摘要生成器(但这类设计现在更倾向用线程局部变量或无状态函数)
- 注意:如果只是多个线程各自拼自己的字符串,那还是用 StringBuilder,完全没必要为“假共享”买单
- 现代开发中,真正需要 StringBuffer 的地方越来越少,多数并发字符串处理已转向不可变 + 函数式组合或使用
ThreadLocal<stringbuilder></stringbuilder>
一个简单判断流程
遇到字符串拼接或构建任务,按顺序问自己:
- 这个字符串最后要不要改?→ 不改 → String
- 要改,但只在一个线程里跑?→ 是 → StringBuilder
- 要改,且多个线程同时往同一个对象里写?→ 是 → StringBuffer;否则 → 回到 StringBuilder
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










