a.可变不可变
首先String是不可改变的对象,可以理解为常量。StringBuffer和StringBuilder这两种对象都是可变的。
1.String 底层使用一个不可变的字符数组 private final char value[],所以它内容不可变。String 为不可变对象,一旦被创建,就不能修改它的值。对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去。
2.StringBuffer和StringBuilder都继承了AbstractStringBuilder底层使用的是可变字符数组:char[]value。StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立, 如: StringBuffer sb = new StringBuffer(); 不能通过赋值符号对他进行赋值。 如 sb = "welcome to here!";//error。对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append()方法。 sb.append("hello");
b.线程安全
String中的对象是不可变的,也就可以理解为常量, 显然线程安全 。
因为StringBuffer的方法(如append()方法)是带同步锁(synchronized),因此StringBuffer线程是安全,但效率较低,StringBuilder线程是不安全的,但是效率较高。
@Override
@HotSpotIntrinsicCandidate
public synchronized StringBuffer append(int i) {
toStringCache = null;
super.append(i);
return this;
}
@Override
@HotSpotIntrinsicCandidate
public StringBuilder append(int i) {
super.append(i);
return this;
}
最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。效率比较String < StringBuffer < StringBuilder。所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。