system.arraycopy是java中用于高效数组片段复制的native方法,在arraylist中用于扩容时迁移旧数据和删除时前移后续元素:扩容调用arraycopy(elementdata, 0, newelements, 0, size),删除调用arraycopy(elementdata, index+1, elementdata, index, size-index-1)。

System.arraycopy 是 Java 中一个本地(native)方法,用于高效地复制数组片段。它不经过 JVM 的普通字节码执行路径,而是直接由 JVM 调用底层 C/C++ 实现,因此性能远高于手动 for 循环拷贝。在 ArrayList 的底层实现中,它被频繁用于两个关键操作:扩容(add)和删除元素(remove),本质都是对内部数组 elementData 的结构调整。
扩容时用 arraycopy 搬移旧数据
当调用 add(E e) 且当前容量不足时,ArrayList 会创建一个更大的新数组(通常是原容量的 1.5 倍),然后把原有元素全部复制过去。这个复制过程就是 System.arraycopy 的典型使用场景:
- 源数组是原
elementData - 源起始位置是 0
- 目标数组是新建的更大数组
- 目标起始位置也是 0
- 复制长度为原数组实际元素个数(
size)
例如,原数组长度为 10、已存 8 个元素;扩容后新数组长度为 15,就用 arraycopy(elementData, 0, newElementData, 0, 8) 把前 8 个元素搬过去,再把新元素放到索引 8 的位置。
删除元素时用 arraycopy 挤掉空位
调用 remove(int index) 删除中间某个元素时,ArrayList 不会留空洞,而是把该位置之后的所有元素向前移动一位。这个“左移”动作正是靠 System.arraycopy 高效完成的:
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
- 源数组和目标数组都是同一个
elementData - 源起始位置是
index + 1 - 目标起始位置是
index - 复制长度为
size - index - 1
比如数组有 [A,B,C,D,E](size=5),删除索引 2(即 C),就执行 arraycopy(elementData, 3, elementData, 2, 2),把 D、E 向前挪一位,结果变成 [A,B,D,E,_],最后将末尾置为 null 并减少 size。
为什么不用 Arrays.copyOf?
Arrays.copyOf 内部其实也调用了 System.arraycopy,但它封装了“分配新数组 + 复制”的整套逻辑。而 ArrayList 在扩容时需要精确控制新数组大小(如按 1.5 倍规则计算),在删除时又需原地搬移,所以直接调用 arraycopy 更灵活、更轻量——避免多余对象分配或边界检查开销。
注意:arraycopy 不做类型检查和越界校验(由 JVM 保证)
它只做基本的数组引用非空和索引范围检查(如负数、超长),但不会验证元素类型是否兼容(比如从 Object[] 复制到 String[] 不报错,但后续强转可能出错)。这也是它快的原因之一。正因如此,ArrayList 在设计上确保传入参数合法,比如复制长度不会超过源/目标数组可写范围。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










