java字符串“+”运算符在编译期常量拼接时直接合并为字面量并存入常量池,运行期含变量时自动转为stringbuilder链式调用;循环中应手动使用stringbuilder以避免重复创建对象。

Java中字符串连接运算符“+”在编译期和运行期的行为不同,其底层并不直接创建多个String对象,而是由编译器自动优化为StringBuilder(或StringBuffer)调用,以提升性能。
编译期常量拼接:直接合并为字面量
当“+”操作的所有操作数都是编译期常量(如字符串字面量、final基本类型或字符串常量)时,Javac会在编译阶段完成拼接,生成单个字符串字面量,不涉及任何运行时对象创建。
-
例如:
String s = "a" + "b" + "c";编译后等价于String s = "abc"; - 该结果存入字符串常量池,仅占用一份内存
运行期变量拼接:自动转为StringBuilder
只要“+”中存在至少一个非编译期常量(如普通局部变量、方法返回值),Javac会将整个表达式重写为StringBuilder的链式调用,避免频繁创建不可变String对象。
-
例如:
String s = "a" + x + "c";(x为String变量)会被编译为类似:new StringBuilder().append("a").append(x).append("c").toString() - Java 9+进一步优化:使用更轻量的
StringConcatFactory生成高效字节码,但语义仍等价于StringBuilder逻辑
循环内慎用+:手动StringBuilder更可控
虽然单个“+”表达式会被优化,但在循环中连续使用“+”仍可能触发多次StringBuilder创建与扩容,造成冗余对象和性能损耗。
-
反例:
String s = ""; for (int i=0; i<n i s><br> 每次“+=”都会新建StringBuilder(初始容量16)、拷贝旧内容、追加、再toString——O(n²)时间复杂度</n> -
正解: 显式复用StringBuilder:
StringBuilder sb = new StringBuilder(); for (int i=0; i<n i sb.append string s="sb.toString();</code"></n>
注意StringBuffer与线程安全
早期Java版本(如5之前)曾使用StringBuffer替代StringBuilder,但自Java 5起,默认生成的是StringBuilder——它非线程安全、无同步开销,性能更高。
- 只有在多线程共享拼接场景下,才需显式选用StringBuffer
- 普通方法内局部拼接无需考虑线程安全,StringBuilder是更优选择
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











