1. String
1.1. 类图
1.2. String类的特性
因为String类经常用到,所以JVM在堆中有一个区域存储:字符串常量池。
每当创建字符串常量时,JVM会首先检查字符串常量池,如果该字符串已经存在常量池中,那么就直接返回常量池中的实例引用
。如果字符串不存在常量池中,就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性,常量池中一定不存在两个相同的字符串。
2. StringBuilder
2.1. 类图
3. StringBuffer
3.1. 类图
3.2. StringBuffer是怎么实现线程安全的?
3.2.1. 对比:
StringBuilder.java
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
StringBuffer.java
@Override
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str);
return this;
}
对比之后可以看出,StringBuffer实现线程安全的方法是用了sync锁。
4. AbstractStringBuilder
StringBuilder和StringBuffer都继承于此类。
AbstractStringBuilder.java
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
// 扩容 x2+2
ensureCapacityInternal(count + len);
// 复制 调用String类的方法,具体是: System.arraycopy
str.getChars(0, len, value, count);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
int newCapacity = value.length * 2 + 2;
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
newCapacity = Integer.MAX_VALUE;
}
value = Arrays.copyOf(value, newCapacity);
}