StringBuilder源码解析
StringBuilder
StringBuilder
是一个继承AbstractStringBuilder
,实现Serializable
和CharSequence
接口的类
public final class StringBuilder extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{
// 此处不粘贴源码
}
初始化
1.StringBuilder
public StringBuilder(String str) {
//调用父类构造方法创建一个定长的空数组,参数传入:字符串长度+16,看1.1
super(str.length() + 16);
// 向空数组中填数据,看1.2
append(str);
}
1.1 父类AbstractStringBuilder
构造方法
char[] value;// 存储字符串内容
AbstractStringBuilder(int capacity) {
value = new char[capacity];// new一个定长的数组
}
1.2 StringBuilder.append
方法
public StringBuilder append(String str) {
super.append(str);//调用父类append方法实现,看1.2.1
return this;
}
1.2.1 父类AbstractStringBuilder.append
方法
int count;//长度计算值:记录value的长度,默认初始值:0
public AbstractStringBuilder append(String str) {
// 判断传入的字符串是否为null
if (str == null)
return appendNull();
int len = str.length();//再次获取字符串长度
ensureCapacityInternal(count + len);//创建时,count=0,看1.2.1.1
//调用String类的getChars方法,生成一个定长的新数组,将str的数据拷贝进value中,这一步结束后value完成赋值
str.getChars(0, len, value, count);
count += len;// 长度计算值+=当前数组长度
return this;
}
1.2.1.1 父类AbstractStringBuilder.ensureCapacityInternal
方法
/**
* @param minimumCapacity append方法中传入的count+len
*
*/
private void ensureCapacityInternal(int minimumCapacity) {
// overflow-conscious code
// 判断传入的参数(长度)是否大于刚生成的数组长度
if (minimumCapacity - value.length > 0) {
/**
* 若大于,证明刚生成的数组容量不满足要求
* 1.调用newCapacity计算扩容后总量(看1.2.1.1.1)
* 2.调用Arrays.copyOf方法,重新生成一个数组,并将原数组数据拷贝进去
* */
value = Arrays.copyOf(value,newCapacity(minimumCapacity));
}
}
1.2.1.1.1 newCapacity 获取“待扩容的数组长度”
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 2^31-1 -8
private int newCapacity(int minCapacity) {
// overflow-conscious code
int newCapacity = (value.length << 1) + 2;// 计算扩容后的数组长度,将原来的数组扩容1倍多2
if (newCapacity - minCapacity < 0) {
// 若“待扩容后的数组长度”还是小于“要求最小扩容量”,则直接使用“要求最小扩容量”作为“待扩容后的数组长度”
newCapacity = minCapacity;
}
/**
* 再一次验证,这次时为了防止容量越界,若MAX_ARRAY_SIZE都小于“待扩容后的数组长度”,看1.2.1.1.1.1
* */
return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
? hugeCapacity(minCapacity)
: newCapacity;
}
Arrays.copyOf
方法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; }
1.2.1.1.1.1 AbstractStringBuilder.hugeCapacity
方法
/**
* 取“待扩容后的数组长度”,在“待扩容后的数组长度”大于MAX_ARRAY_SIZE成立时被调用
* 1.验证“待扩容后的数组长度”是否大于Integer.MAX_VALUE(2^31-1),若大于证明“待扩容后的数组长度”超界了,直接抛异常
* 2.上一步验证通过,接着判断“待扩容后的数组长度”和MAX_ARRAY_SIZE(2^31-1 -8)谁大,取最大者
*/
private int hugeCapacity(int minCapacity) {
if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE)
? minCapacity : MAX_ARRAY_SIZE;
}
由源码可知
StringBuilder
的大量操作都是由其父类AbstractStringBuilder
实现的StringBuilder
是线程不安全类StringBuilder
有容量限制,且当前容量不满足要求时会重新创建char[]
,都由父类AbstractStringBuilder
实现;网上都在说StringBuilder动态扩容,这种说法也对也不对,对是因为它在不满足要求时的确扩容了,而且扩容量给到了原容量的1倍+2,一定程度上这会减少new char[]造成的消耗,不对是因为它不在原数组上扩容,是直接创建新char[newLenth],然后拷贝旧数组数据实现扩容StringBuilder
初始化数组长度:字符串长度+16
Tips
其实在操作StringBuilder的变量时跟一跟源码,就会发现,
AbstractStringBuilder
实现了StringBuilder
的绝大部分方法,就连存储字符串的char[] value
也是由AbstractStringBuilder
提供的
本文来自博客园,作者:勤匠,转载请注明原文链接:https://www.cnblogs.com/JarryShu/articles/18179193
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现