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是线程安全的。