java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,以下总结出他们三个的不同之处。
一、可变与不可变
/** The value is used for character storage. */
private final char value[];
由String类的源码中可以看出String类使用char数组保存字符串,用final来进行修饰,由此可见是不可变的。
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
public final class StringBuilder
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
由以上源码可见,StringBuffer和StringBuilder都是继承了AbstractStringBuilder类,在AbstractStringBuilder类中:
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value;
AbstractStringBuilder类中用char数组来存储字符串,由源码可知,StringBuffer和StringBuilder两种对象都是可变的。
二、线程安全
由上面的源码分析可知,String中的对象是不可变的,也就可以理解为常量,所以线程安全。
@Override
public synchronized int length() {
return count;
}
@Override
public synchronized int capacity() {
return value.length;
}
@Override
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
/**
* @since 1.5
*/
@Override
public synchronized void trimToSize() {
super.trimToSize();
}
/**
* @throws IndexOutOfBoundsException {@inheritDoc}
* @see #length()
*/
@Override
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
上为StringBuffer类中一部分源码,在StringBuffer类中,对方法使用synchronized进行了加锁,所以是线程安全的。
StringBuilder并没有对方法加同步锁,所以是非线程安全的。
三、StringBuffer和StringBuilder的相同与异同
相同点:
1.都可以对字符串进行操作;
2.有公共的父类AbstractStringBuilder。
异同点:
1.在多线程环境下,StringBuffer是线程安全的,StringBuilder是线程不安全的。
2.如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。