StringBuilder默认初始容量为16,源自无参构造调用super(16)分配char[]数组;扩容公式为原容量×2+2,若仍不足则直接设为所需最小容量,触发条件是count+新增长度>value.length。

Java 中 StringBuilder 默认初始容量是 16,扩容不是简单翻倍,而是按公式计算新容量:先尝试 原容量 × 2 + 2,若仍不够,则直接设为所需最小容量。
默认初始容量怎么来的
无论是否传参,StringBuilder 都继承自 AbstractStringBuilder,其底层维护一个可变的 char[] value 数组:
- 无参构造(
new StringBuilder())→ 底层数组长度 = 16 - 传入字符串构造(
new StringBuilder("abc"))→ 数组长度 = 字符串长度 + 16(即 3 + 16 = 19) - 显式指定容量(
new StringBuilder(32))→ 数组长度 = 32,不加额外偏移
扩容触发条件
扩容只在真正“放不下”时发生,判断依据是:
-
count(当前已用字符数,即length()返回值) -
value.length(当前数组长度,即capacity()) - 当
count + 新增字符数 > value.length时,下一次append()就会触发扩容
扩容公式与实际增长节奏
扩容分两步计算新容量:
立即学习“Java免费学习笔记(深入)”;
- 先算默认扩容值:
newCapacity = value.length << 1 + 2(等价于value.length * 2 + 2) - 再和“至少需要的容量”(即
count + 新增长度)比较,取较大者作为最终容量
举例:
- 初始容量 16,追加 20 字符 → 16×2+2 = 34 ≥ 20 → 实际扩到 34
- 初始容量 16,追加 50 字符 → 34 < 50 → 直接扩到 50
为什么是 ×2 + 2 而不是 ×2 或 +16
这个设计兼顾小容量和边界安全:
- 对极小初始值(如 1):1×2+2 = 4,避免频繁小步扩容
- 防止
newCapacity计算为 0(比如位运算0 << 1仍是 0,+2 后得 2,可安全建数组) - 比固定 +16 更适应不同规模场景,又比纯 ×2 更保守,减少内存浪费


















