三者的区别在于可变性与线程安全性:

String 是不可变对象,内部 char 数组(JDK 9 起为 byte 数组)被 final 修饰且不提供修改方法,任何"修改"操作(拼接、替换)都创建新对象。不可变带来线程安全、可缓存 hashCode、能放入常量池复用等好处,但频繁拼接会产生大量临时对象。

StringBuilder 是可变字符序列,操作(append、insert)直接在内部数组上进行,无同步,线程不安全但性能最好,是单线程字符串拼接的首选——Javac 也会把 + 拼接优化为 StringBuilder(但循环内拼接仍需显式使用,否则每次循环新建一个 StringBuilder)。

StringBuffer 与 StringBuilder 功能几乎相同,但方法用 synchronized 修饰,线程安全,代价是同步开销。实际开发中很少需要跨线程共享一个拼接器,所以 StringBuffer 基本被 StringBuilder 取代。

StringBuilder sb = new StringBuilder();
for (String s : parts) sb.append(s); // 循环拼接的正确姿势
String result = sb.toString();

追问方向:String 不可变如何实现与加固(反射破坏、数组拷贝)?StringBuffer 的同步能否保证复合操作的原子性?(不能,仍可能需要外部同步)

(约 340 字)