可通过反射获取elementdata数组长度,结合add操作前后对比,精准验证arraylist扩容:空列表首次add后容量从0→10;容量10时第11次add触发扩容至15,符合1.5倍增长逻辑。

可以通过构造特定容量的 ArrayList,结合反射或内部状态检查,再配合 add 操作和 size / capacity 对比,精准验证扩容是否在预期位置触发。关键不是只看 size 增长,而是确认底层 elementData 数组长度是否发生改变。
准备可观察容量变化的测试环境
使用无参构造创建 ArrayList,确保走默认扩容路径(首次 add → 容量从 0→10);或用带初始容量构造(如 new ArrayList(5)),便于控制触发点。避免使用 Collections.emptyList() 等不可变实例。
由于 elementData 是私有字段,需借助反射获取其 length:
- 调用 getDeclaredField("elementData") 并设为 accessible
- 用 Array.getLength() 获取当前数组长度
- 每次 add 后立即检查该值,对比前后是否变化
验证首次扩容(0→10)
对空 ArrayList 调用 add 第一个元素时,elementData.length 应从 0 变为 10。注意:此时 size = 1,但容量已跃升。测试断言应写为:
- add 前:Array.getLength(elementData) == 0
- add 后:Array.getLength(elementData) == 10
若使用带参构造 new ArrayList(0),效果相同;若传入 10,则首次 add 不会扩容。
验证后续扩容(如 10→15)
在容量为 10 的列表中连续 add 元素,直到第 11 次调用 add —— 此时 size + 1 = 11 > 10,应触发 grow(),新容量为 oldCapacity + (oldCapacity >> 1) = 15。
- add 第 10 个后:length 仍为 10
- add 第 11 个后:length 应变为 15
- 可额外验证:newCapacity 计算逻辑是否符合 1.5 倍向上取整(如 15→22,22→33)
覆盖边界场景:addAll 和指定位置插入
addAll(Collection) 会一次性检查 total size + 新增数量是否超限,可能跳过多次单步 add 的中间扩容;add(int index, E e) 同样触发 ensureCapacityInternal(size + 1),逻辑一致。
- 用 ArrayList(5) + addAll(Arrays.asList(1,2,3,4,5,6)) → 总数达 11,应扩容
- 在 size=10 的列表中调用 add(0, x) → size+1=11,同样触发扩容
- 断言重点仍是 elementData.length 是否按预期增长
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











