String:
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
可以看到String是被保存到一个value[ ] 里的,而且不管是方法还是类都被final修饰着,所以String是不可变的,每次修改都会产生一个新的对象,修改的次数多了,会产生很多无用的对象.
而StringBuffer和StringBuilder是对对象本身进行操作,而不是生成新的对象
StringBuffer:
展示一下他的关系图
继承了抽象类AbstractStringbulider,可以看到很多重写的方法都加上了synchronized关键字,所以他是线程安全的,但正因为如此,他的性能也会有所影响,所以一般的操作会更多的使用StringBuilder
@Override
public synchronized StringBuffer append(double d) {
toStringCache = null;
super.append(d);
return this;
}
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2
*/
@Override
public synchronized StringBuffer delete(int start, int end) {
toStringCache = null;
super.delete(start, end);
return this;
}
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
* @since 1.2
*/
@Override
public synchronized StringBuffer deleteCharAt(int index) {
toStringCache = null;
super.deleteCharAt(index);
return this;
}
.......
.......
.......
StringBuilder:
先来看看他的关系图
可以看到跟StringBuffer一样,一样继承AbstractStringBuilder这个抽象类,以及实现的接口也是一样的,所以实现的方法和功能有很多跟StringBuffer是一样( append,insert,delete等等 )的,但是点进去可以看到StringBuilder的方法都是没有关键字修饰的
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder deleteCharAt(int index) {
super.deleteCharAt(index);
return this;
}
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder replace(int start, int end, String str) {
super.replace(start, end, str);
return this;
}
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
*/
@Override
public StringBuilder insert(int index, char[] str, int offset,
int len)
{
super.insert(index, str, offset, len);
return this;
}
....
....
因此可以看出StringBuilder是线程不安全的,但是性能比StringBuffer占优
总的来说平时一般单线程,没有原子性上的要求的话,还是多数使用StringBuilder比较多,性能好,除非特殊要求的地方