Java 字符串拼接用 +、StringBuilder 还是 StringBuffer?一篇给你终极答案

在 Java 开发中,字符串拼接几乎无处不在。

但是很多人依然搞不清:

  • "a" + "b" 和 StringBuilder.append() 性能差多少?
  • StringBuffer 和 StringBuilder 到底该选哪个?
  • 为什么有时 + 也能很快?

本文将从原理、性能、线程安全、最佳实践四个方面,帮你彻底搞懂这个问题。


1. 三者的基本认识

1.1 + 运算符

  • 是 Java 的语法糖。
  • 在编译期 ,javac 会将非循环内的字符串常量拼接优化为一个常量。
  • 在运行期 ,+ 会被编译器转成使用 StringBuilder (早期版本是 StringBuffer,JDK5 后改成 StringBuilder)。
  • 本质上 + 并不是直接的"字符串相加",而是 创建 StringBuilder → append → toString。

1.2 StringBuilder

  • 可变 的字符序列(String 是不可变的)。
  • 非线程安全,但速度快。
  • 适用于单线程、多次拼接的场景。
  • API:append()、insert()、delete() 等。

1.3 StringBuffer

  • 和 StringBuilder 类似,但线程安全 (方法上有 synchronized)。
  • 在多线程并发修改同一字符串时安全,但性能比 StringBuilder 略低。
  • 单线程下不推荐使用。

2. 工作原理 & 编译器优化

2.1 常量折叠(编译期优化)

java 复制代码
String s = "a" + "b" + "c";
System.out.println(s); // abc

编译后字节码中会直接变成:

java 复制代码
String s = "abc";

没有运行期开销。


2.2 循环内拼接

java 复制代码
String s = "";
for (int i = 0; i < 1000; i++) {
    s = s + i;
}

编译器会转成:

java 复制代码
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(s).append(i);
    s = sb.toString();
}
  • 每次 toString() 都会创建新 String 对象 → 大量内存浪费,性能差。

2.3 手动 StringBuilder

java 复制代码
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i);
}
String s = sb.toString(); // 一次性生成
  • 只有一次 toString() 调用,性能更优。

3. 性能对比

一个简单的 10000 次拼接测试(单线程):

方法 时间 (ms) 特点
+ (循环内) 400+ 大量中间对象
StringBuilder 3~5 性能最佳
StringBuffer 8~10 线程安全,稍慢

(测试环境:JDK 17,本地单线程,结果随机器差异)


4. 线程安全问题

场景 选择
单线程 StringBuilder(性能优先)
多线程,同一实例被多个线程修改 StringBuffer(保证同步)
多线程,但每个线程有自己实例 StringBuilder(无共享状态)

5. 最佳实践建议

  1. 能用常量直接拼接就用常量(编译期优化,无运行时开销)。

  2. 循环中多次拼接 → 直接用 StringBuilder。

  3. 多线程共享可变字符串 → 用 StringBuffer。

  4. 拼接规模已知 → 初始化 StringBuilder 容量:

    java 复制代码
    StringBuilder sb = new StringBuilder(1024);

    避免频繁扩容。


6. 小结对比表

特性 + StringBuilder StringBuffer
语法简洁 ✅ ❌ ❌
性能(循环内) ❌ ✅ 中等
线程安全 ❌ ❌ ✅
适用场景 少量拼接 单线程多拼接 多线程共享

✅ 一句话记忆:

少量拼接用 +,单线程多次拼接用 StringBuilder,多线程共享用 StringBuffer。

相关推荐
Wang's Blog1 分钟前
Java 项目实战: 外卖平台优化-使用Redis作为缓存产品与TTL配置
java·redis·缓存
谢亮_vipxieliang12 分钟前
ValidX 在微服务架构中的验证策略
java·spring boot·spring·spring cloud·hibernate
其实防守也摸鱼15 分钟前
内网安全防护实践:从攻击视角理解防御要点
java·前端·安全·架构·自动化·nps
我是小白呀22 分钟前
17-企业Workflow引擎怎么选:定时、队列、n8n、Temporal与Camunda
java·开发语言·人工智能·dubbo·workflow
海宇AI33 分钟前
零信任架构实战:基于海宇车型识别精准构建自动化车队评估微服务
java·人工智能·架构·自动化
xixiaoyunya35 分钟前
Spring Boot 3 统一响应与全局异常处理实战
java·spring boot·后端
JavaGuide1 小时前
DeepSeek Harness 官方桌面端终于有了!
前端·后端
一条破秋裤1 小时前
Linux 线程分离与主动取消:pthread_detach、pthread_cancel
java·linux·jvm
SFLYQ1 小时前
隔离内网下 AI Agent 工程实战
后端·agent·ai编程