Java作为广泛使用的编程语言,字符串操作是日常开发中的高频场景,其中字符串拼接的实现方式有多种,不同方式的底层逻辑和性能表现存在明显区别,了解这些差异能帮助开发者写出更高效的代码。

Java中常见的字符串拼接方式
1. 使用加号(+)拼接
这是最直观的拼接方式,写法简单,适合少量字符串拼接的场景。示例代码如下:
public class StringConcatDemo {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
// 使用加号拼接字符串
String result = str1 + " " + str2;
System.out.println(result); // 输出 Hello World
}
}
2. 使用String的concat方法
concat是String类提供的实例方法,专门用于拼接字符串,调用后会返回新的字符串对象。示例代码如下:
public class StringConcatDemo {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
// 使用concat方法拼接
String result = str1.concat(" ").concat(str2);
System.out.println(result); // 输出 Hello World
}
}
3. 使用StringBuilder拼接
StringBuilder是可变字符序列,拼接时不会创建大量临时对象,适合频繁拼接的场景。示例代码如下:
public class StringConcatDemo {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
// 使用StringBuilder拼接
StringBuilder sb = new StringBuilder();
sb.append(str1).append(" ").append(str2);
String result = sb.toString();
System.out.println(result); // 输出 Hello World
}
}
4. 使用StringBuffer拼接
StringBuffer和StringBuilder功能类似,但方法是线程安全的,适合多线程场景下的字符串拼接。示例代码如下:
public class StringConcatDemo {
public static void main(String[] args) {
String str1 = "Hello";
String str2 = "World";
// 使用StringBuffer拼接
StringBuffer sbf = new StringBuffer();
sbf.append(str1).append(" ").append(str2);
String result = sbf.toString();
System.out.println(result); // 输出 Hello World
}
}
5. 使用StringJoiner拼接
StringJoiner是Java 8引入的工具类,适合需要添加分隔符的拼接场景,比如拼接集合元素。示例代码如下:
import java.util.StringJoiner;
public class StringConcatDemo {
public static void main(String[] args) {
// 使用StringJoiner拼接,指定分隔符为空格
StringJoiner joiner = new StringJoiner(" ");
joiner.add("Hello").add("World");
String result = joiner.toString();
System.out.println(result); // 输出 Hello World
}
}
不同拼接方式的性能差异分析
我们可以从底层实现和适用场景两个维度分析不同拼接方式的性能差异:
- 加号(+)拼接:在Java编译阶段,少量加号拼接会被优化为StringBuilder操作,但如果是循环中使用加号拼接,每次循环都会创建新的StringBuilder对象,产生大量临时对象,性能较差。
- concat方法:底层是通过复制字符数组实现拼接,每次调用都会创建新的String对象,拼接次数多时性能不如StringBuilder。
- StringBuilder:内部维护可变的字符数组,拼接时直接操作数组,不会频繁创建新对象,单线程场景下性能最优。
- StringBuffer:方法和StringBuilder基本一致,但所有公开方法都加了synchronized锁,保证了线程安全,不过也带来了额外的性能开销,单线程场景下性能略低于StringBuilder。
- StringJoiner:底层基于StringBuilder实现,适合有分隔符的拼接场景,性能和StringBuilder接近,代码可读性更高。
拼接方式选择建议
结合不同方式的特性,我们可以按照以下场景选择对应的拼接方式:
| 场景 | 推荐拼接方式 |
|---|---|
| 少量字符串、非循环场景 | 加号(+)或concat方法 |
| 单线程、频繁拼接或循环拼接 | StringBuilder |
| 多线程、频繁拼接场景 | StringBuffer |
| 需要指定分隔符的拼接(如拼接集合元素) | StringJoiner |
验证性能差异的测试示例
我们可以通过循环拼接10万次字符串来直观对比不同方式的耗时,示例代码如下:
public class StringConcatPerformanceTest {
public static void main(String[] args) {
int loopCount = 100000;
String baseStr = "test";
// 测试加号拼接耗时
long startTime = System.currentTimeMillis();
String plusResult = "";
for (int i = 0; i < loopCount; i++) {
plusResult += baseStr;
}
long plusTime = System.currentTimeMillis() - startTime;
System.out.println("加号拼接耗时:" + plusTime + "ms");
// 测试StringBuilder拼接耗时
startTime = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < loopCount; i++) {
sb.append(baseStr);
}
String sbResult = sb.toString();
long sbTime = System.currentTimeMillis() - startTime;
System.out.println("StringBuilder拼接耗时:" + sbTime + "ms");
// 测试StringBuffer拼接耗时
startTime = System.currentTimeMillis();
StringBuffer sbf = new StringBuffer();
for (int i = 0; i < loopCount; i++) {
sbf.append(baseStr);
}
String sbfResult = sbf.toString();
long sbfTime = System.currentTimeMillis() - startTime;
System.out.println("StringBuffer拼接耗时:" + sbfTime + "ms");
}
}
运行上述代码可以明显看到,循环场景下加号拼接的耗时远高于StringBuilder和StringBuffer,而StringBuilder的耗时略低于StringBuffer,和之前的分析结论一致。
Java字符串拼接StringBuilderStringBuffer性能差异修改时间:2026-06-19 17:06:21