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对象)



浙公网安备 33010602011771号