String StringBuilder StringBuffer

String

    String 是字符串常量,不可变。其存储是由final修饰的char数组。

1
2
/**value用来存储字符串**/
private final char value[];

StringBuilder

    StringBuilder继承了AbstractStringBuilder,实际数据存储在AbstractStringBuilder中的value字符数组中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* 初始化一个空的String Builder,容量为16
*/
public StringBuilder() {
super(16);
}

/**
* 初始化一个空的String Builder并制定初始容量
*/
public StringBuilder(int capacity) {
super(capacity);
}

/**
* 使用字符串初始化StringBuilder
*/
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}

    AbstractStringBuilder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 存储字符串
*/
char[] value;

/**
* 字符数量
*/
int count;

/**
* 指定value的大小构造对象
*/
AbstractStringBuilder(int capacity) {
value = new char[capacity];
}

StringBuffer

     StringBuffer同样继承了AbstractStringBuilder,它与StringBuilder不同的是,其本身有一个字符串缓存,且它的操作都以synchronized关键字修饰。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 最后一次toString返回的缓存。每次修改StringBuffer时清空
*/
private transient char[] toStringCache;

/**
* 初始化一个空的String Buffer,容量为16
*/
public StringBuffer() {
super(16);
}

@Override
public synchronized StringBuffer append(String str) {
toStringCache = null; //清空缓存
super.append(str);
return this;
}

@Override
public synchronized String toString() {
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count); //无缓存时从value中获取
}
return new String(toStringCache, true);
}

总结

  • String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。
  • 在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。