1.String
public final class String implements……{
private final char value[];//存储数组本身
private int hash;//用来存储计算后的哈希值
}
- 总结:
final修饰类,String类不可继承;
final修饰char[],说明存放的数据不可变(引用不可变,但具体的值是可变的)。
String慢就慢在每次连接字符串时都会创建一个新的String对象。
2.StringBuilder、AbstractStringBuilder
基本上StringBuilder中所有的方法都是调用其抽象父类AbstractStringBuilder中的方法实现功能的,因此搞懂AbstractStringBuilder就搞懂了StringBuilder。
- StringBuilder:
public final class StringBuilder extends AbstractStringBuilder implements ……{
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
…………
}
- AbstractStringBuilder:
abstract class AbstractStringBuilder implements ……{
char[] value;//数据存储
int count;//实际长度
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();//1 append空字符串
int len = str.length();
ensureCapacityInternal(count + len);//2 扩容
str.getChars(0, len, value, count);//3 把str中的字符复制到value中去
count += len;
return this;
}
//append空字符串:char数组末尾加上一个"null"字符串
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
//扩容:如果char数组空间不够了,会重新创建一个足够长的数组,然后把原来的字符拷贝过来
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
}
- 总结:
final修饰类,StringBuilder类也是不可继承的;
char[]没用final修饰,说明存放的数据是可变的,所以字符串的伸缩性比String好。
3.StringBuffer
没想到StringBuffer也是实现了AbstractStringBuilder抽象类,
public final class StringBuffer extends AbstractStringBuilder implements……{
//用来缓存上一次的toString结果,但是一旦StringBuffer被修改,此缓存就会失效
private transient char[] toStringCache;//用transient关键字标记的成员变量不参与序列化过程
@Override
public synchronized StringBuffer append(Object obj) {//通过加锁来保证线程安全
toStringCache = null;//一旦发生修改,让缓存失效
super.append(String.valueOf(obj));//调用AbstractStringBuilder中的相应方法
return this;
}
}
- 总结:
final修饰类,StringBuffer类也是不可继承的;
char[]没用final修饰,说明存放的数据是可变的,所以字符串的伸缩性比String好。
append方法上了synchronized锁,所以是线程安全的。