system.arraycopy 是 java 中最直接、最可控的数组复制方式,其五个参数(src、srcpos、dest、destpos、length)分别指定源数组、起始索引、目标数组、写入位置和复制长度,缺一不可且需严格校验边界与类型兼容性。

System.arraycopy 是 Java 中最直接、最可控的数组复制方式,它的五个参数共同决定了“从哪来、到哪去、搬多少、怎么摆”。用错一个,轻则数据错位,重则运行时异常;用对了,一行代码就能完成精确的片段搬运。
五个参数各司其职,缺一不可
方法签名是:public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)。每个参数都承担明确语义:
- src:源数组对象,不能为空(否则抛 NullPointerException);可以是任意类型数组(int[]、String[]、自定义对象数组等)
- srcPos:源数组中开始读取的索引位置,必须 ≥ 0;且 srcPos + length ≤ src.length,否则抛 ArrayIndexOutOfBoundsException
- dest:目标数组对象,也不能为空;类型需与 src 兼容(如 String[] 可复制给 Object[],但不能给 Integer[])
- destPos:目标数组中开始写入的索引位置,必须 ≥ 0;且 destPos + length ≤ dest.length,否则越界
- length:要复制的元素个数,必须 ≥ 0;为 0 时合法(空操作),为负数则抛 NegativeArraySizeException
复制起始点与长度的组合逻辑
很多人误以为“复制第 2 到第 4 个元素”就该写 arraycopy(arr, 2, dst, 0, 4),其实这是错的——length 表示数量,不是结束索引。
- 复制 arr[2]、arr[3]、arr[4](共 3 个)→
arraycopy(arr, 2, dst, 0, 3) - 想把 arr 后 3 个元素复制到 dst 开头 →
arraycopy(arr, arr.length - 3, dst, 0, 3) - 若 arr 长度不确定,建议先校验:
int len = Math.min(3, arr.length),再传入len避免越界
同一数组内复制:自动处理重叠,但位置决定方向
当 src 和 dest 是同一个数组时,JVM 会根据 srcPos 和 destPos 的相对关系,自动选择前向或后向拷贝(类似 memmove),保证结果正确。
-
arraycopy(arr, 0, arr, 1, 4):把前 4 个元素整体后移一位([a,b,c,d,e] → [a,a,b,c,d]) -
arraycopy(arr, 1, arr, 0, 4):把后 4 个元素整体前移一位([a,b,c,d,e] → [b,c,d,e,e]) - 关键点:只要区间重叠,就不能用普通 memcpy 逻辑;而 arraycopy 内部已封装安全策略,你只需按业务意图写清楚起止即可
类型兼容性:编译期不报错,运行时才校验
由于参数类型都是 Object,编译器无法在写代码时检查类型是否匹配,真正校验发生在 JVM 执行时:
- 允许向上转型:Object[] ← String[]、int[] ← Integer[](自动装箱数组不适用,注意区分)
- 禁止向下/跨类型:int[] → double[]、String[] → Integer[] 会抛 ArrayStoreException
- 安全做法:优先保持 src 和 dest 类型一致;若需转换,改用 Stream 或 Arrays.copyOf + 泛型构造











