public AbstractStringBuilder insert(int offset, String str) {
if ((offset < 0) || (offset > length()))
//如果offset不在索引范围,则抛出异常:
throw new StringIndexOutOfBoundsException(offset);
if (str == null)
str = "null";
int len = str.length();
//原来字符串数组内部容量确保没有问题,传入当前数组存放字符串长度+插入字符串长度
ensureCapacityInternal(count + len);
//把原来数组从offset位置及以后的字符串复制到offset+len去,复制的长度是原来数组长度减去offset前的长度
System.arraycopy(value, offset, value, offset + len, count - offset);
//把待插入的字符串复制到offset的位置去
str.getChars(value, offset);
count += len;
return this;
}
/**
* This method has the same contract as ensureCapacity, but is
* never synchronized.
*/
private void ensureCapacityInternal(int minimumCapacity) {
// 如果插入字符串后总长度比原来申请的总长度大,则需要进行容量扩展
if (minimumCapacity - value.length > 0)
expandCapacity(minimumCapacity);
}
/**
* This implements the expansion semantics of ensureCapacity with no
* size check or synchronization.
*/
void expandCapacity(int minimumCapacity) {
//先试着扩展到原来容量的2倍+2
int newCapacity = value.length * 2 + 2;
//如果插入的字符串太长,直接用传入的参数
if (newCapacity - minimumCapacity < 0)
newCapacity = minimumCapacity;
//如果计算的容量小于0,溢出了,表示出了内存问题
if (newCapacity < 0) {
if (minimumCapacity < 0) // overflow
throw new OutOfMemoryError();
//直接给一个很大的值作为扩展后的容量
newCapacity = Integer.MAX_VALUE;
}
//基于新的数组长度,把原来的数组内容复制到新申请长度的数组
value = Arrays.copyOf(value, newCapacity);
}
public static char[] copyOf(char[] original, int newLength) {
//申请扩展后字符串长度的字符数组
char[] copy = new char[newLength];
//把原来数组内容复制到新的数组
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}