外观
String, StringBuffer,StringBuilder的区别是什么
String、StringBuffer 和 StringBuilder 是 Java 中用于处理字符串的三个类,它们的主要区别如下:
- 可变性
String:是不可变的。当一个 String 对象被创建后,它包含的字符序列就不能被改变。如果对 String 进行拼接、替换等操作,实际上是创建了一个新的 String 对象。例如:
String str = "hello";
str += " world";
这里 str 原本指向的 "Hello" 对象并没有改变,而是创建了一个新的 "Hello World" 对象,并让 str 指向这个新对象。
StringBuffer:是可变的。它内部维护了一个可变的字符序列,对 StringBuffer 进行拼接、插入、删除等操作时,不会创建新的对象,而是直接在原对象的基础上进行修改。例如:
StringBuffer sb = new StringBuffer("Hello");
sb.append(" World");
此时 sb 指向的对象内容从 "Hello" 变成了 "Hello World",对象本身并没有改变。
StringBuilder:同样是可变的,和 StringBuffer 一样,对其进行操作时会直接修改原对象的字符序列。例如:
StringBuilder sbuilder = new StringBuilder("Hello");
sbuilder.append(" World");
sbuilder 指向的对象内容也会直接被修改。
- 线程安全性
String:由于其不可变性,String 是线程安全的。多个线程同时访问同一个 String 对象时,不会出现数据不一致的问题,因为它的内容不会被改变。
StringBuffer:是线程安全的。它的所有公开方法都使用了 synchronized 关键字进行同步,这意味着在多线程环境下,同一时间只有一个线程可以对
StringBuffer 对象进行操作,从而保证了线程安全。例如:
StringBuffer sb = new StringBuffer();// 多个线程调用 append 方法时会进行同步
sb.append("Hello");
StringBuilder:是非线程安全的。它没有使用 synchronized 关键字进行同步,在多线程环境下,如果多个线程同时对同一个 StringBuilder 对象进行操作,可能会出现数据不一致的问题。例如:
StringBuilder sbuilder = new StringBuilder();// 多个线程同时操作可能会出错
sbuilder.append("Hello");
- 性能
String:由于每次对 String 进行修改操作都会创建新的对象,频繁的修改操作会导致大量的对象创建和垃圾回收,性能较低。例如在循环中进行字符串拼接时,会产生大量的临时对象。
StringBuffer:因为其线程安全的特性,使用了同步机制,这会带来一定的性能开销。在单线程环境下,这种同步开销是不必要的,会影响性能。
StringBuilder:没有同步开销,在单线程环境下,性能比 StringBuffer 要高。因此,在单线程环境下如果需要频繁修改字符串,优先选择 StringBuilder。
- 使用场景
String:适用于字符串不经常发生变化的场景,例如存储常量字符串、作为方法的参数等。
StringBuffer:适用于多线程环境下需要对字符串进行频繁修改的场景,例如在多线程的日志记录器中使用。
StringBuilder:适用于单线程环境下需要对字符串进行频繁修改的场景,例如在循环中进行字符串拼接。