stringbuilder扩容时机是当count+新增字符数>value.length时立即触发;新容量计算分三步:先得minimumcapacity=count+新增字符数,再按公式算newcapacity=(oldcapacity

扩容触发时机很明确
StringBuilder 不是按“用了多少字符”来决定是否扩容,而是看“接下来要放多少”是否超出当前底层数组空间。只要 当前已用长度(count) + 即将新增的字符数 > 底层数组长度(value.length),就会立刻触发扩容。这个判断发生在 append、insert、replace 等操作的最开始,不是执行完才发现不够。
新容量不是简单翻倍,而是分步计算
扩容时的新容量不是直接 old × 2,而是按三步走:
- 先算出最低需要多少:minimumCapacity = count + 新增字符数
- 再按公式算基础容量:newCapacity = (oldCapacity
- 取两者中较大的那个:如果 newCapacity
比如初始容量 16,append 20 个字符 → minimumCapacity = 20,newCapacity = 34,34 ≥ 20,最终容量为 34;若 append 100 个字符 → minimumCapacity = 100,但 34
扩容本质是一次数组复制
扩容过程不神秘,核心就是三件事:
- 分配一个新 byte[](JDK 9+)或 char[](JDK 8 及之前),长度为上一步算出的 newCapacity
- 调用 System.arraycopy() 把旧数组里 count 个有效字符完整拷贝过去
- 把内部 value 引用指向这个新数组,旧数组等待 GC 回收
这一步是扩容里开销最大的部分,时间复杂度 O(n),但比频繁创建 String 对象带来的 GC 压力小得多。
有兜底和上限保护
扩容不是无限制的:
- 如果计算出的 newCapacity 小于 0(比如整数溢出),会抛 OutOfMemoryError
- 如果 newCapacity 超过 Integer.MAX_VALUE - 8(JVM 数组长度上限),也会抛同名异常
- +2 的设计不只是凑整,还防止初始容量为 0 或 1 时首次扩容仍不足用
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











