java一维数组长度固定,动态扩展实为创建新数组、复制数据、更新引用;需用arrays.copyof或system.arraycopy实现,自建dynamicarray应区分capacity与size,扩容建议1.5倍,多数场景优先使用arraylist。

Java 一维数组长度不可变,所谓“动态扩展”本质是创建新数组、复制数据、更新引用的过程。这不是语法层面的扩容,而是应用层的模拟策略——关键不在能不能做,而在怎么做更合理、更可控。
明确长度固定这一前提
数组在 JVM 中分配的是连续内存块,长度写入对象头且运行时不可修改。任何“改长度”的操作,都是放弃旧数组、启用新数组。这意味着:
- 每次扩容/缩容都涉及内存分配与数据复制,有开销
- 原数组若无其他引用,将被 GC 回收,但频繁触发 GC 会影响性能
- 多个变量引用同一数组时(如 arr1 = arr2),仅替换某个引用不会影响其他变量
手动扩缩容的核心操作方式
不依赖集合类时,常用两种高效复制手段:
- Arrays.copyOf(arr, newSize):最简洁,自动处理截断或补默认值(int 补 0,引用类型补 null)
- System.arraycopy(src, 0, dest, 0, len):更底层,适合需精确控制复制范围或避免创建中间对象的场景
例如从长度为 3 的数组扩展到 6:
int[] old = {1, 2, 3};<br>int[] updated = Arrays.copyOf(old, 6); // 结果:[1, 2, 3, 0, 0, 0]
封装工具类时的关键设计点
若需自建 DynamicArray,以下细节决定稳定性:
- 区分容量(capacity)和实际元素数(size):前者是数组 length,后者是有效数据个数,遍历时必须用 size 作上界
- 扩容倍率建议 1.5 倍(而非翻倍),平衡空间利用率与复制频次;缩容阈值可设为 capacity 的 1/4,避免抖动
- 泛型实现需用 Object[] + 类型转换,不能 new T[size];remove 后及时置 null 防止内存泄漏(尤其存大对象时)
何时该放弃手写,转向 ArrayList
除非满足以下任一条件,否则直接用 ArrayList 更稳妥:
- 嵌入式环境对 jar 包体积极度敏感
- 需要完全掌控内存布局(如与 JNI 交互)
- 教学目的,为理解集合底层机制而刻意模拟
ArrayList 已优化扩容阈值、批量复制、并发安全提示(fail-fast)等细节,其“额外开销”在绝大多数业务场景中可忽略不计。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











