优先选 stringbuilder,单线程场景性能更优;多线程且需共享实例时才用 stringbuffer,因其方法加 synchronized 保证线程安全。两者底层均基于可变字符数组,支持原地修改与扩容,api 高度一致,迁移成本低。

选 StringBuilder 还是 StringBuffer,关键看线程环境和性能要求。单线程用 StringBuilder,多线程且需同步时才用 StringBuffer。
可变性与底层实现一致
两者都继承自 AbstractStringBuilder,底层用 char[](JDK 9+ 优化为 byte[])存储,数组不加 final,支持原地修改、扩容、append、insert、delete 等操作,不会像 String 那样每次拼接都生成新对象。
- 初始容量默认为 16,超出时自动扩容(通常翻倍 + 2)
- 构造时指定合理初始容量(如预估最终长度的 1.2 倍),可减少数组复制开销
- Java 21 起两者都新增 repeat() 方法,支持重复拼接字符串
线程安全是核心分水岭
StringBuffer 所有 public 修改方法(append、insert、reverse 等)都加了 synchronized,能保证多线程并发调用时数据一致性;StringBuilder 完全无锁,靠开发者自行保障线程隔离。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 若在 Servlet、线程池任务、定时器等共享上下文中拼接日志或响应体,必须用 StringBuffer
- 局部变量、方法内临时拼接、Stream.collect() 中的容器,用 StringBuilder 即可
- 即使使用了 StringBuffer,也不代表整个业务逻辑线程安全——它只保护自身状态
性能差异真实存在但常被高估
在纯 CPU 密集型拼接场景下,StringBuilder 比 StringBuffer 快约 10%–20%,差距来自 synchronized 的进出开销。但实际应用中,I/O、GC、算法复杂度往往掩盖该差异。
- 编译器对 String 拼接已优化:简单表达式如 "a" + obj + "b" 会被自动转成 StringBuilder.append()
- 循环内用 += 拼接 String 仍会反复创建 StringBuilder 实例,应显式声明 StringBuilder 变量
- 若需带分隔符拼接(如 list 转 csv),优先考虑 StringJoiner,语义更清晰且复用 StringBuilder
兼容性与日常建议
两者 API 几乎完全一致,除线程安全外无行为差异。迁移成本极低:把 StringBuffer 改成 StringBuilder,只需去掉同步顾虑;反之则加锁即可。
- 新项目默认用 StringBuilder,除非明确需要跨线程共享同一实例
- 不要因“可能并发”而盲目选 StringBuffer——先确认是否真共享实例,再评估锁粒度
- String 不适合频繁修改;StringBuffer 不适合单线程高频场景;StringBuilder 是大多数情况下的务实选择
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










