数组拷贝是ArrayList动态扩容、克隆及自定义集合实现的核心机制,依赖System.arraycopy高效迁移数据,支持浅拷贝逻辑与内存优化操作。

数组拷贝不是“配角”,而是ArrayList这类基于数组的集合能动态伸缩的核心支撑。它直接决定扩容效率、克隆行为和线程安全边界。
扩容时靠System.arraycopy高效迁移数据
ArrayList每次add导致容量不足时,会创建新数组,并把旧元素搬过去。这个“搬家”动作不靠循环赋值,而是调用System.arraycopy——底层用内存块复制,避免逐个索引寻址,性能显著优于for循环。
- 扩容比例通常是1.5倍(JDK 7+),比如从10扩到15
- 拷贝起点是原数组索引0,长度是当前有效元素个数(size),不是整个原数组长度
- 目标数组起始位置也是0,确保元素顺序不变
构造副本时Arrays.copyOf简化浅拷贝逻辑
new ArrayList(otherList) 或 otherList.clone() 内部都依赖Arrays.copyOf。它封装了数组创建+拷贝两步,一行代码完成“申请新空间+复制内容”。
- 参数只需传原数组和目标长度,自动处理类型检查和越界保护
- 若指定长度大于原数组,末尾补默认值(如int为0,引用类型为null)
- 本质仍是调用System.arraycopy,但对开发者更友好
浅拷贝与深拷贝的关键分水岭在这里
所有基于数组拷贝的副本操作(包括clone、构造函数、addAll)默认都是浅拷贝:新数组里存的是原对象的引用,不是新对象。
- 基本类型(int、String等不可变类型)没问题,改值不影响原集合
- 引用类型(如Person实例)要注意:修改对象属性,两边都会看到变化
- 真要隔离修改,得手动遍历并调用每个元素的clone(),或用序列化实现深拷贝
自己实现集合时,拷贝控制着性能和内存使用
自定义数组型List(如ExtList)必须自己管理扩容和删除逻辑,而System.arraycopy就是核心工具。
- 插入中间位置:先用arraycopy把后半段右移,再填入新元素
- 删除中间元素:用arraycopy把后半段左移覆盖,相当于“擦除”
- 缩容判断(如length / size ≥ 3)后,同样靠arraycopy把有效数据搬进小数组

















