system.arraycopy是java中最高效、最底层的数组拷贝方式,为native方法,直接操作内存地址,不创建新数组、无类型检查与边界校验,开销极小;适用于性能敏感场景,支持跨数组拷贝、原地移动及协变类型转换。

System.arraycopy 是 Java 中最高效、最底层的数组拷贝方式,适合对性能敏感的场景,比如从大数组中提取片段、合并数组、或实现动态扩容逻辑。
为什么选 System.arraycopy 而不是 Arrays.copyOf 或 clone?
System.arraycopy 是 native 方法,直接操作内存地址,不创建新数组对象(需提前分配目标数组),也不做类型检查和边界校验(这些由调用者负责),因此开销极小。而 Arrays.copyOf 内部其实也调用了 System.arraycopy,但多了一次 new 数组的操作;clone() 只支持一维数组且语义固定,灵活性不足。
- 适合已知目标容量、追求极致性能的场景
- 支持任意源/目标数组偏移量和长度控制,可精确截取片段
- 支持跨数组拷贝(比如从 A 的第 3 位拷贝 5 个元素到 B 的第 1 位)
核心参数详解与安全使用要点
调用格式:System.arraycopy(src, srcPos, dest, destPos, length)
五个参数必须全部合法,否则抛出 ArrayIndexOutOfBoundsException 或 NullPointerException:
- src:源数组,不能为 null
- srcPos:源起始索引(包含),必须 ≥ 0 且 ≤ src.length
- dest:目标数组,不能为 null,且类型需与 src 兼容(如 Object[] ← String[] 合法,int[] ← long[] 不合法)
- destPos:目标起始索引(包含),必须 ≥ 0 且 ≤ dest.length
- length:拷贝元素个数,必须 ≥ 0,且满足 srcPos + length ≤ src.length,destPos + length ≤ dest.length
建议在调用前手动校验,尤其在封装工具方法时:
if (src == null || dest == null || length src.length ||
destPos dest.length) {
throw new IllegalArgumentException("Invalid array copy parameters");
}
实战:从原始数组中提取指定范围的子数组
这是最常见的需求——类似 Python 的切片 arr[2:7]。Java 没有原生切片语法,但用 System.arraycopy 配合 new 数组即可高效实现:
public static String[] subArray(String[] arr, int from, int to) {
if (arr == null || from arr.length || from > to) {
throw new IllegalArgumentException();
}
String[] result = new String[to - from];
System.arraycopy(arr, from, result, 0, to - from);
return result;
}
调用示例:subArray(new String[]{"a","b","c","d","e"}, 1, 4) → 返回 {"b","c","d"}。
注意:to 是**结束索引(不包含)**,符合 Java 惯例,避免混淆。
进阶技巧:原地移动、覆盖式拷贝与类型转换边界
System.arraycopy 支持源和目标为同一数组,可用于“左移”、“右移”等原地操作(只要不重叠冲突):
- 将数组前 3 个元素移到末尾(循环右移):
System.arraycopy(arr, 0, arr, arr.length-3, 3) - 删除中间一段(如跳过索引 2~4):先拷贝前段到目标位置,再拷贝后段接上
类型方面,它支持协变拷贝(如 String[] → Object[]),但不支持基本类型与引用类型互转,也不支持 int[] ↔ long[] 自动扩缩容——这些必须手动循环处理。
若需 deep copy 多维数组,需逐层调用 System.arraycopy,或改用序列化/JSON 工具。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











