对象可变
String 类中使用 final 关键字修饰字符数组来保存字符串,private final char value[]
,因此 String 对象是不可变的。而 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder 类,在 AbstractStringBuilder 中,也是使用字符数组来保存字符串的 char[] value
, 但是没有用 final 关键字修饰,所以这两种对象都是可变的。
StringBuilder 与 StringBuffer 的构造方法,都是调用了父类的构造方法,也就是 AbstractStringBuilder 实现的。
AbstractStringBuilder.java
abstract class AbstractStringBuilder implements Appendable, CharSequence {
int count;
char[] value;
AbstractStringBuilder() {
}
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}
}
线程安全
String 中的对象是不可变的,可以理解为常量,所以是线程安全的。AbstractStringBuilder 是 StringBuilder 与 StringBuffer 的公共父类,定义了一些公共的字符串的基本操作,如 expandCapacity()、append()、insert()、indexOf() 等公共方法。StringBuffer 对方法加了同步锁,或者对调用的方法加了同步锁,所以是线程安全的。StringBuilder 没有对方法进行加锁,所以是非线程安全的。
执行性能
对 String 对象进行操作时,每次都会生成一个新的 String 对象,指针将指向新的 String 对象。StringBuffer 每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。相同情况下,使用 StringBuilder 相比于使用 StringBuffer,能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
适用场景
- 操作少量的数据:String
- 单线程下操作大量数据:StringBuilder
- 多线程下操作大量数据:StringBuffer