system.arraycopy 是 jvm 底层原语,直接内存块拷贝,仅支持原生数组,参数需类型兼容,执行浅拷贝,适用于扩容、删除前移、截取等高效场景。

System.arraycopy 是 JVM 提供的底层原语,它不走 Java 字节码循环逻辑,而是直接调用本地方法(如 C/C++ 实现),在内存层面做块拷贝,因此比 for 循环快得多。它本身不支持“自定义数组”——Java 中所有数组都是 JVM 原生类型(如 int[]、String[]、MyClass[]),不存在用户可重写复制行为的“自定义数组类”。但你可以通过合理使用 System.arraycopy 高效完成各类数组复制场景。
明确适用前提:必须是 JVM 原生数组
你不能对 ArrayList、LinkedList 或自己写的 ArrayWrapper 类直接用 System.arraycopy。它只接受以下参数:
- 源数组(任意引用或基本类型数组)
- 源起始索引(int)
- 目标数组(类型需兼容,如
Object[]可接String[],但int[]不能赋给long[]) - 目标起始索引(int)
- 要复制的元素个数(int)
例如正确用法:
String[] src = {"a", "b", "c"};String[] dst = new String[5];
System.arraycopy(src, 0, dst, 1, 3); // dst[1..3] ← src[0..2]
高效复制对象数组时注意浅拷贝语义
System.arraycopy 对引用类型数组只复制引用值,不调用构造函数或 clone 方法,属于**浅拷贝**。如果你需要深拷贝(如每个元素都 new 一份),它帮不上忙,得配合循环 + clone 或序列化等手段。但多数场景(如缓存扩容、临时切片、队列平移)只需浅拷贝,此时它是最优解。
常见高效模式:
- 动态数组扩容:
System.arraycopy(oldArr, 0, newArr, 0, oldLen) - 删除中间元素后前移:
System.arraycopy(arr, i+1, arr, i, len-i-1) - 截取子数组(配合新建数组):
System.arraycopy(src, from, dst, 0, length)
避免常见性能陷阱
虽然很快,但误用会抵消优势:
- 不要在小数组上过度优化:长度
-
类型不匹配会抛
ArrayStoreException:比如把String[]复制到Integer[]—— 运行时检查,非编译期 -
越界检查由 JVM 完成,但失败抛
IndexOutOfBoundsException:确保srcPos ≥ 0、dstPos ≥ 0、length ≥ 0,且不超出各自数组边界
替代方案对比:什么情况下不该用它
当你的“自定义数组”其实是集合类(如 MyList),应优先复用标准 API:
- 复制
List→ 用new ArrayList(original)或original.subList() - 需要类型转换/过滤/映射 → 用 Stream:
list.stream().map(...).toArray() - 跨类型数组转换(如
int[]→Integer[])→ 必须循环或 IntStream,arraycopy无能为力
真正需要手写复制逻辑的场景极少,绝大多数时候,System.arraycopy 就是 JVM 给你准备好的、最高效的数组搬运工。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











