length()返回当前字符个数,capacity()返回内部数组最大容量;前者是“已用”,后者是“预备”,扩容仅在append导致length超过capacity时触发,按×2+2阶梯增长或直接满足需求。

直接看返回值含义:length() 返回当前字符串实际字符个数,capacity() 返回内部 char[] 数组能容纳的最大字符数——两者根本不是同一维度的指标。
length 是“用了多少”,capacity 是“准备了多少”
就像一个水杯:length 是当前装了多少水,capacity 是杯子最大能装多少。往 StringBuilder 里 append 字符,length 随之增加;只有当 length 超过 capacity 时,系统才会换一个更大的“杯子”,capacity 才会变大。
- 新建空对象:
new StringBuilder()→ length = 0,capacity = 16 - 初始化带字符串:
new StringBuilder("abc")→ length = 3,capacity = 19(16 + 3) - 只调用
delete()或setLength(0):length 变小甚至归零,capacity 不变
扩容规则决定 capacity 如何变化
capacity 不是线性增长,而是按需阶梯式扩容。触发条件只有一个:append 后 length > 当前 capacity。
- 初始 capacity = 16,追加到第 17 个字符时 → 新 capacity = 16 × 2 + 2 = 34
- 再追加到第 35 个字符时 → 新 capacity = 34 × 2 + 2 = 70
- 若某次 append 直接超出当前 capacity 很多(比如从 16 一下加 100 个字符),新 capacity 会直接设为所需最小值(≥ length),而非机械套用 ×2+2
常见误判点要避开
这几个坑容易让人混淆 length 和 capacity:
立即学习“Java免费学习笔记(深入)”;
- 传单个 char 构造:
new StringBuilder('a')实际调用的是int构造器,capacity = 97('a' 的 ASCII 码),length = 0 - 以为 capacity 不变就代表没扩容 → 错!capacity 只在真正需要时才变,平时保持不变是常态
- 用 capacity 判断字符串是否为空 → 错!空字符串 length = 0,但 capacity 往往仍是 16 或更大
- 认为 trimToSize() 是“清空” → 它只是把 capacity 缩到等于当前 length,不改变内容也不重置 length
怎么查、怎么控,一句话到位
随时用 length() 和 capacity() 查状态;想提前规划空间,就用 new StringBuilder(预估大小) 或 ensureCapacity(最小需求),避免运行时频繁扩容影响性能。


















