优先用concat()拼接两个非空字符串,因底层零拷贝、无StringBuilder开销;+适合含变量的简单拼接或全常量场景,编译期优化充分且可读性高。
string.concat() 适合拼接少量字符串(通常 2 个),底层直接复用原字符串的 char 数组(java 8 及以前)或 byte 数组(java 9+),避免创建 stringbuilder,开销极小;而 + 运算符在编译期会自动优化为 stringbuilder.append(),但仅限于编译期常量拼接,运行时拼接仍需动态构建对象。
何时用 concat() 更合适
适用于明确知道只有两个字符串、且至少一个是变量(非全常量)的场景,比如:
- 用户输入 + 固定后缀:
username.concat("_temp") - 从配置读取的前缀 + 动态生成的 ID:
prefix.concat(id.toString()) - 避免隐式装箱或临时 StringBuilder 创建,对 GC 敏感的轻量逻辑
何时 + 更自然且不慢
多数日常场景中,+ 更简洁、可读性高,且 JVM 优化充分:
- 全编译期常量:
"Hello" + " " + "World"→ 直接编译为"Hello World" - 含 1–2 个变量的简单拼接:
"User: " + name + ", age: " + age→ 编译为 StringBuilder 链式调用,性能接近 concat() - IDE 和 JIT 均能识别并优化,无需手动替换为 concat()
性能对比的关键细节
不要只看微基准测试数字,注意这些实际影响:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
-
concat(null)抛NullPointerException,而"a" + null得到"anull"—— 行为不同,不能无脑替换 - concat() 每次只接受一个参数,拼接多个字符串需链式调用:
s1.concat(s2).concat(s3),不如s1 + s2 + s3直观 - Java 9 引入紧凑字符串(byte[] + coder),concat() 在同编码下可共享底层数组,零拷贝;+ 运算符在运行时仍需数组复制(StringBuilder.ensureCapacity)
- 真实业务中,字符串拼接 rarely 是瓶颈,可读性与维护性优先级更高
简单验证示例(Java 17)
用 JMH 测得 2 字符串拼接(一个变量 + 一个字面量):
-
a.concat(b):平均约 3.2 ns/op -
a + b:平均约 4.1 ns/op(因 StringBuilder 初始化和 append 开销略高) - 差距不到 1 ns,且随字符串长度增加,两者差异迅速收敛
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










