StringBuilder初始容量为16(无参构造),字符串构造时为str.length()+16,显式指定则直接取该值;扩容触发条件是count+新增长度>当前capacity;新容量取max(原capacity×2+2, 最小需容量)。

Java StringBuilder 初始容量设置的面试题,核心是考你是否真正理解构造逻辑和扩容边界,不是背数字,而是会算、能推、懂为什么。
初始容量怎么算出来的
关键看用的是哪种构造方式:
- 无参构造 new StringBuilder() → 底层数组长度 = 16(源码 super(16))
- 传字符串构造 new StringBuilder("abc") → 底层数组长度 = 字符串长度 + 16 = 3 + 16 = 19
- 显式指定容量 new StringBuilder(32) → 底层数组长度 = 32(不加偏移)
扩容触发条件怎么判断
不是“满了才扩”,而是“马上要放不下时才扩”。判断公式很明确:
当前已用字符数(count) + 即将追加的字符数 > 当前数组长度(value.length)
立即学习“Java免费学习笔记(深入)”;
满足这个不等式,下一次 append 就会触发扩容。比如 capacity=16,当前 length=15,再 append 2 个字符 → 15+2=17 > 16 → 扩容。
扩容后的新容量怎么算
不是简单 ×2,而是两步计算:
- 先算:新容量候选值 = 原容量 × 2 + 2
- 再比:取“候选值”和“至少需要的最小容量(即 count + 新增长度)”中的较大者
举例:
- 初始 capacity=16,append 20 字符 → 需要至少 20,候选值=16×2+2=34 → 实际扩容到 34
- 初始 capacity=16,append 50 字符 → 需要至少 50,候选值=34 50
为什么设计成 ×2+2 而不是 ×2 或 +16
这个公式兼顾了三件事:
- 避免小容量频繁扩容:比如初始为 1,×2+2=4,比 ×2=2 更稳妥
- 防止整数溢出或零值:0×2+2=2,能安全创建数组;纯位运算
- 比固定 +16 更适应不同规模:小字符串省空间,大字符串不浪费太多内存
不复杂但容易忽略。


















