测试说明:下面该段测试使用的是jdk12,被native修饰的方法查看源码方式在AndroidXRef
下面通过一段简单的测试代码来探究StringBuffer的insert()方法的底层实现:
public class Solution{
public static void main(String[] args){
StringBuffer sb=new StringBuffer("i am make atest");
sb.insert(11, " insert ");
System.out.println(sb.toString());
}
}
以下是Java的部分底层源码:
/**
* @throws StringIndexOutOfBoundsException {@inheritDoc}
*/
//注意:此处StringBuffer的insert被synchronized修饰,说明是线程安全的
@Override
public synchronized StringBuffer insert(int offset, String str) {
toStringCache = null;
super.insert(offset, str);
return this;
}
public AbstractStringBuilder insert(int offset, String str) {
checkOffset(offset, count);//检查插入位置是否合法,没有越界
if (str == null) {
str = "null";
}
int len = str.length();//获取要插入的字符串长度,8
ensureCapacityInternal(count + len);//15+8=23
shift(offset, len);//shift译为转移
count += len;//字符串长度更新
putStringAt(offset, str);
return this;
}
private void shift(int offset, int n) {
//看不了native修饰的底层源码,盲猜是扩容,创建新的数组,容量扩大
System.arraycopy(value, offset << coder,
value, (offset + n) << coder, (count - offset) << coder);
}
//注意:从注解中发看出jdk12用的是HotSpot虚拟机
@HotSpotIntrinsicCandidate
public static native void arraycopy(Object src, int srcPos,
Object dest, int destPos,
int length);
private final void putStringAt(int index, String str) {
if (getCoder() != str.coder()) {
inflate();
}
str.getBytes(value, index, coder);
}
//COMPACT_STRINGS为true,都返回coder==0,而UTF16的值为1
final byte getCoder() {
return COMPACT_STRINGS ? coder : UTF16;
}
byte coder() {
return COMPACT_STRINGS ? coder : UTF16;
}
void getBytes(byte dst[], int dstBegin, byte coder) {
if (coder() == coder) {
//在前面扩容的基础上,将内容插入进去
System.arraycopy(value, 0, dst, dstBegin << coder, value.length);
} else { // this.coder == LATIN && coder == UTF16
StringLatin1.inflate(value, 0, dst, dstBegin, value.length);
}
}