跳转至

String、StringBuffer、StringBuilder 的区别?

结论速查

String StringBuffer StringBuilder
可变性 不可变 可变 可变
线程安全 安全(不可变) 安全(方法 synchronized) 不安全
性能 低(每次拼接新对象)
使用场景 少量字符串操作 多线程共享 单线程拼接

一、String 不可变

String s = "a";
s = s + "b";   // 不是改原对象,是新建一个 "ab"

底层是 private final char[] value(JDK9 后是 byte[] + 编码)。

二、StringBuffer

public final class StringBuffer extends AbstractStringBuilder {
    public synchronized StringBuffer append(String str) { ... }
}

所有 public 方法都 synchronized,线程安全,但性能差。

三、StringBuilder

JDK 5 引入,与 StringBuffer 方法一样,只是去掉了 synchronized。

StringBuilder sb = new StringBuilder();
sb.append("a").append("b");

四、拼接性能对比

// 反例:循环拼接
String s = "";
for (int i = 0; i < 10000; i++) {
    s += i;   // 每次新建 StringBuilder,再 toString,慢
}

// 推荐
StringBuilder sb = new StringBuilder(10000);
for (int i = 0; i < 10000; i++) {
    sb.append(i);
}

JDK 编译器对 + 做了优化,会编译成 StringBuilder.append,但循环外每次 new 一个,仍慢。

五、JDK 9 的变化

String 底层从 char[] 改成 byte[] + coder: - 纯 ASCII 用 1 字节存,省内存。 - 有非 ASCII 用 UTF-16,2 字节。

面试加分

  • 单线程用 StringBuilder,多线程共享用 StringBuffer。
  • 实际开发几乎不用 StringBuffer,多线程场景用局部变量 + StringBuilder 即可。