StringBuffer源码解析

Posted yuancoco

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了StringBuffer源码解析相关的知识,希望对你有一定的参考价值。

 
在重写ArrayList的toString方法时,查看了StringBuffer的源码.

//new StringBuffer("[");构造方法
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
//super(str.length() + 16);调用父类构造
AbstractStringBuilder(int capacity) {
//初始化value数组 char[] value;length为参数字符串长度+16
value = new char[capacity];
}
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
//保证内部数组容量,拼接字符串str长度+内部数组实际长度 大于 buffer对象内部value数组长度则扩容内部数组
//内部数组实际长度指{1,2,3,null,null},实际长度为3,数组长度为5
ensureCapacityInternal(count + len);
//
str.getChars(0, len, value, count);
count += len;
return this;
}
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
// 判断是否超过内部数组容量
if (minimumCapacity - value.length > 0) {
value = Arrays.copyOf(value,
newCapacity(minimumCapacity));
}
}
//original内部数组扩容为newLength长度
public static char[] copyOf(char[] original, int newLength) {
char[] copy = new char[newLength];
//Math.min(original.length, newLength)复制长度为原来数组的长度
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
//新数组长度计算算法
private int newCapacity(int minCapacity) {
// overflow-conscious code
// 原来数组长度*2再+2
int newCapacity = (value.length << 1) + 2;
if (newCapacity - minCapacity < 0) {
//如果原来数组长度*2再+2还是 小于 拼接字符串str长度+内部数组实际长度 则设置新数组长度为:拼接字符串str长度+内部数组实际长度
newCapacity = minCapacity;
}
//判断新数组长度是否大于Integer.MAX_VALUE - 8 int类型最大值,大于则抛出OutOfMemoryError内存不足异常
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}

private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
// str.getChars(0, len, value, count);
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
if (srcBegin < 0) {
throw new StringIndexOutOfBoundsException(srcBegin);
}
if (srcEnd > value.length) {
throw new StringIndexOutOfBoundsException(srcEnd);
}
if (srcBegin > srcEnd) {
throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
}
//this.value数组是str字符串的内部数组,从index=0开始复制,复制到目标数组(dst:buffer的value内部数组)
//目标数组的下标位置(从index=count的位置开始复制:也就是value[count]开始复制),要复制的长度:str字符串的长度
//要复制的数组(源数组),复制源数组的起始位置,目标数组,目标数组的下标位置,要复制的长度
System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
}
 

以上是关于StringBuffer源码解析的主要内容,如果未能解决你的问题,请参考以下文章

Java String源码解析

StringBuffer 和 StringBuilder 总结

jdk源码解析--AbstractStringBuilder类

Java String源码解析

StringBuffer 源码分析

java.lang.StringBuffer源码分析