Skip to content

String、StringBuffer 和 StringBuilder 的区别

String、StringBuffer 和 StringBuilder 是 Java 中用于处理字符串的三种类,它们的主要区别在于可变性、线程安全性和性能。

String

  • 特性:String 是不可变的,即字符串对象一旦创建,其内容不能被修改。每次修改字符串(如拼接、截取等)都会生成新的字符串对象。
  • 存储位置:String 对象是存储在字符串常量池中的(如果使用字面量创建)。
  • 线程安全性:由于 String 是不可变的,它是线程安全的。
  • 性能:因为每次修改都会产生新的对象,频繁操作字符串时,性能较低,内存开销大。
Java
String str = "Hello";
str = str + " World"; // 会创建一个新的字符串对象,而不是修改原对象
System.out.println(str); // 输出 Hello World

当执行 String str = "Hello"; 时,创建了一个字符串对象 str,它包含字符串 "Hello"。
当执行 str = str + " World"; 时,实际上发生了以下事情:
1. Java 创建了一个新的字符串对象,包含了 "Hello World"。
2. 然后,将新的字符串对象的引用赋值给 str 变量。
3. 原来的字符串对象 "Hello" 并没有被修改,它仍然存在于内存中,直到没有引用指向它,此时垃圾回收器会回收它。

StringBuffer

  • 特性:StringBuffer 是可变的,支持修改字符串内容,不会产生新的对象。
  • 线程安全:StringBuffer 使用了同步(synchronized)机制,因此是线程安全的。
  • 性能:由于使用了同步机制,StringBuffer 的性能比 StringBuilder 要低,但比 String 更高效,适合多线程环境。
Java
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World"); // 直接在原对象上修改内容
System.out.println(sb); // 输出: Hello World

StringBuilder

  • 特性:StringBuilder 也提供了可变字符串的功能,方法和 StringBuffer 几乎相同。
  • 线程安全性:StringBuilder 不是线程安全的,因为它没有使用同步机制。
  • 性能:由于没有同步开销,StringBuilder 的性能比 StringBuffer 更高,适合单线程环境。
Java
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 修改同一个对象
System.out.println(sb); // 输出: Hello World

使用建议

  • String:适用于字符串不经常变更的场景,比如常量、少量拼接等。
  • StringBuffer:适用于多线程环境下字符串频繁修改的场景。
  • StringBuilder:适用于单线程环境下字符串频繁修改的场景。

示例对比

Java
// 使用 String
String str = "Hello";
for (int i = 0; i < 1000; i++) {
    str += " World"; // 每次循环都会生成新的字符串对象
}

System.out.println(str);

// 使用 StringBuilder
StringBuilder sb = new StringBuilder("Hello");
for (int i = 0; i < 1000; i++) {
    sb.append(" World"); // 在同一对象上修改
}

System.out.println(sb);

结果:

  • String 的方式效率低,消耗大量内存。
  • StringBuilder 的方式性能高,避免了对象创建的开销。

最后更新: