Java 字符串拼接原理
原文:Java 字符串拼接原理
我们知道 Java 可以直接使用加号+
来拼接字符串。
字符串+
拼接的本质是使用StringBuilder.append()
(已在Java8
测试通过),最终如果要赋值给字符串变量时,会调用toString()
。
/** * 字符串追加 */ @Test public void testStrAppend() { /* * + 之前先隐式实例化 StringBuilder 对象 * 每次 + 都是 append,期间不会 toString * 最后赋值给字符串时,会隐式调用 toString() 得到结果字符串 */ String abc = "2"; String def = "3"; String str = "1" + abc + def; System.out.println(str); }
![]() |
特殊地,如果是字符串常量拼接,编译器会在编译期自动优化到一起,例如"1" + "2" + "3"
会自动优化为"123"
。
使用+
拼接字符串是 Java 语法糖。
/** * 字符串常量拼接 */ @Test public void testConstantAppend() { // 如果是常量相加,那么编译器在编译为 class 文件时,会自动优化为一个常量 String str = "1" + "2" + "3"; }
![]() |
还需要注意的是在循环中如果使用+=
其实会造成StringBuilder
重复创建,导致资源浪费,因为每次+=
都会 new 一次StringBuilder
,并隐式toString()
赋值给原字符串对象。
/** * 在循环中追加字符串 * 在循环中 += 会造成资源浪费 */ @Test public void testStrAppendInLoop() { /* * 循环中不推荐使用 += * 每次 += 相当于实例化一个新的 StringBuilder,然后调用 append(oldStr)、append(newStr)、toString() * 产生大量的 StringBuilder 对象 */ String str = ""; for (int i = 0; i < 100; i++) { str += i; } System.out.println(str); }
![]() |
总结:
对于字符串使用+
拼接:
-
如果是常量相加,那么在编译器会自动合并为一个常量字符串(只要挨着的常量就会合并,前后声明不影响,例如
"1" + "2" + def + "4" + "5"
会自动合并为"12" + def + "45"
) -
如果与变量相加,那么相加前会初始化
StringBuilder
对象,每次相加都append(str)
,如果赋值给String
,最终会隐式调用toString()
(即只在最后调用一次toString()
,这是我们期望的)
需要注意的是,使用+=
拼接,例如a += 123;
等效于a = a + 123;
,每次+=
都会实例化一个新的StringBuilder
对象,append(a).append(123)
再隐式调用toString()
(注意:每次+=
因为要再次赋值给字符串a
都会隐式toString()
)。
所以,如果在循环中使用+=
,会产生大量StringBuilder
对象(每次相加前都会实例化StringBuilder
对象)和String
对象(每次都会toString()
),造成资源浪费。
最佳实践:
-
普通的字符串拼接,可以使用
+
拼接字符串(与手动创建StringBuilder
对象,调用append()
等效) -
循环中字符串拼接,推荐手动创建
StringBuilder
对象调用append()
,而不是+=
(循环中+=
会创建大量StringBuilder
和String
对象)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix