system.arraycopy是java中高效数组拷贝的核心方法,直接调用jvm本地代码,支持同数组内安全移动、覆盖、插入等操作;其五个参数(src、srcpos、dest、destpos、length)须严格满足非空、类型兼容及边界条件,否则抛出nullpointerexception或arrayindexoutofboundsexception。

System.arraycopy 是 Java 中高效拷贝数组元素的核心方法,它直接调用本地代码(native),比手动循环或 Arrays.copyOf 更快,也更灵活——尤其适合需要移动、覆盖、插入或截取数组片段的场景。
理解 System.arraycopy 的五个参数含义
调用格式为:System.arraycopy(src, srcPos, dest, destPos, length)。每个参数都关键,错一位就可能抛出 ArrayIndexOutOfBoundsException 或静默覆盖错误位置:
- src:源数组,不能为空,否则抛 NullPointerException
- srcPos:从源数组哪个索引开始读(含),必须满足 0 ≤ srcPos ≤ src.length
- dest:目标数组,不能为空,且类型需与 src 兼容(如 int[] → int[],String[] → Object[])
- destPos:往目标数组哪个索引开始写(含),必须满足 0 ≤ destPos ≤ dest.length
- length:要拷贝多少个元素,必须 ≥ 0,且不能超过剩余可用空间:src.length - srcPos 和 dest.length - destPos 中的较小值
常见实用场景与写法示例
无需创建新数组就能完成多数“移动类”操作,避免冗余对象分配:
-
向后平移子数组:把 arr[2]~arr[4] 整体后移一位(即插入空位),可写:
System.arraycopy(arr, 2, arr, 3, 3); —— 注意这里 src 和 dest 是同一数组,且 destPos > srcPos,JVM 内部按倒序拷贝,不会覆盖未读数据 -
前移覆盖腾出开头空间:删除前两个元素,等效于保留 arr[2] 及之后:
System.arraycopy(arr, 2, arr, 0, arr.length - 2); -
合并两个数组片段到第三个数组:将 a[1..3] 和 b[0..1] 拷入 result 前5位:
System.arraycopy(a, 1, result, 0, 3);
System.arraycopy(b, 0, result, 3, 2); -
实现数组扩容后迁移(类似 ArrayList.ensureCapacity):先 new 更大数组,再整体拷贝:
int[] bigger = new int[old.length * 2];
System.arraycopy(old, 0, bigger, 0, old.length);
必须避开的典型陷阱
看似简单,但几个细节极易引发运行时异常或逻辑错误:
- 类型不匹配不报编译错,但运行时报 ArrayStoreException:比如把 String[] 拷进 Object[] 没问题,但反过来把 Integer[] 拷进 String[] 就会失败
- 源/目标是同一数组时,方向决定安全性:若 destPos
- length 为负数直接抛 IllegalArgumentException;为 0 则什么也不做,合法且常用于边界保护
- 数组引用为 null 时立即抛 NullPointerException,建议在调用前显式判空(尤其当参数来自外部输入时)
对比 Arrays.copyOf 和手动循环的适用选择
不是所有场景都该用 arraycopy:
- 需要创建新数组并拷贝全部内容?用 Arrays.copyOf(arr, arr.length) 更简洁,底层其实也调用了 arraycopy
- 只拷贝部分元素且目标数组已存在?arraycopy 是唯一高效选择
- 需要转换类型或过滤元素(如 int[] → String[])?必须手动循环 + 转换,arraycopy 不支持计算或映射
- 对小数组(长度 ?简单 for 循环反而更易读、易断点,性能差异可忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











