Android面试-String、StringBuffer 与 StringBuilder 的区别详解
一、三者概览
在 Java 中,String、StringBuffer 和 StringBuilder 都可以用来表示字符串,但它们在可变性、线程安全性和性能上存在明显差异。理解这些差异,是写出高效 Java 代码的基础。
| 对比项 | String | StringBuffer | StringBuilder |
|---|---|---|---|
| 可变性 | 不可变 | 可变 | 可变 |
| 线程安全 | 安全(不可变天然安全) | 安全(方法加 synchronized) | 不安全 |
| 性能 | 频繁拼接时较差 | 中等 | 最高 |
| 适用场景 | 字符串常量、少量操作 | 多线程环境下的字符串拼接 | 单线程环境下的字符串拼接 |
二、String:不可变字符串
String 内部使用 final 修饰的字符数组(JDK 9 之后为 byte[])存储数据,一旦创建就不能被修改。所有看似“修改”的操作,实际上都是创建了一个新的 String 对象。
String s = "hello";
s = s + " world"; // 实际创建了新对象,原对象不变
System.out.println(s); // hello world
由于不可变,String 可以安全地被多个线程共享,也适合作为 HashMap 的 key。但在循环中频繁拼接字符串时,会产生大量临时对象,性能较差。
提示:字符串常量会存放在字符串常量池中,相同字面量会复用同一个对象。
三、StringBuffer:线程安全的可变字符串
StringBuffer 是可变的字符序列,其大部分方法都使用 synchronized 修饰,因此是线程安全的。多个线程同时操作同一个 StringBuffer 对象时不会出现数据错乱。
StringBuffer sb = new StringBuffer();
sb.append("hello");
sb.append(" world");
System.out.println(sb.toString()); // hello world
由于每次操作都需要获取锁,StringBuffer 在单线程场景下的性能不如 StringBuilder。
四、StringBuilder:非线程安全的高性能可变字符串
StringBuilder 与 StringBuffer 的 API 基本一致,但没有加锁,因此在单线程环境下性能更高。它是绝大多数单线程字符串拼接场景的首选。
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 5; i++) {
sb.append(i).append(",");
}
System.out.println(sb.toString()); // 0,1,2,3,4,
五、性能对比示例
下面通过一个简单示例对比三者在循环拼接时的表现:
public class StringTest {
public static void main(String[] args) {
int count = 10000;
long start = System.currentTimeMillis();
String s = "";
for (int i = 0; i < count; i++) {
s += i;
}
System.out.println("String: " + (System.currentTimeMillis() - start) + " ms");
start = System.currentTimeMillis();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < count; i++) {
buffer.append(i);
}
System.out.println("StringBuffer: " + (System.currentTimeMillis() - start) + " ms");
start = System.currentTimeMillis();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < count; i++) {
builder.append(i);
}
System.out.println("StringBuilder: " + (System.currentTimeMillis() - start) + " ms");
}
}
通常情况下,String 的耗时远高于另外两者,而 StringBuilder 略快于 StringBuffer。
六、如何选择
- String:字符串内容基本不变,或只是少量拼接、作为常量或 Map 的 key 时使用。
- StringBuffer:多线程环境下需要频繁修改字符串时使用,保证线程安全。
- StringBuilder:单线程环境下频繁拼接字符串时使用,性能最佳,是日常开发中最常用的选择。
七、总结
三者的核心区别可以概括为:String 不可变、StringBuffer 可变且线程安全、StringBuilder 可变但非线程安全。实际开发中,优先使用 StringBuilder;只有在明确需要多线程共享同一字符串缓冲区时,才选择 StringBuffer。
使用小程序,查看更多面试题目,随时随地刷题,刷题更方便!


浙公网安备 33010602011771号