System.arraycopy是Java中最底层高效的数组拷贝方法,直接调用JVM本地内存操作指令,仅做严格边界的整块搬运,不创建对象、不装箱、不校验元素值;参数错误立即抛出ArrayIndexOutOfBoundsException或ArrayStoreException。

System.arraycopy 是 Java 中最贴近内存操作的数组工具,不是“复制函数”,而是“地址块搬运指令”。它不创建对象、不触发装箱、不校验元素值,只做严格边界的整块搬移——截取和拼接都靠它,但用错参数就立刻抛异常。
数组截取:从任意位置取一段放进目标容器
截取本质是“局部拷贝”,关键在控制 srcPos 和 length。比如从 byte[] 中取中间 1024 字节:
- 目标数组必须提前 new 好,长度至少为 1024;不能指望 arraycopy 帮你分配
- 写法示例:
System.arraycopy(src, offset, dest, 0, 1024),其中 offset 是起始下标,不是字节偏移量 - 若 offset + 1024 超出 src.length,运行时直接抛 ArrayIndexOutOfBoundsException
- 想截取后覆盖原数组某段?可以,只要 dest 就是 src 本身,且区间不导致关键数据被提前覆盖
两个数组拼接:先算总长,再分段落位
拼接不是语法糖,是两步搬运。核心是第二段拷贝的 destPos 必须等于第一段长度:
- int[] a = {1, 2}; int[] b = {3, 4, 5};
- 目标数组:int[] result = new int[a.length + b.length];
- 第一段:
System.arraycopy(a, 0, result, 0, a.length) - 第二段:
System.arraycopy(b, 0, result, a.length, b.length)—— 这里 a.length 是关键,不是 0,也不是 b.length - 常见错误:destPos 写成 0,结果 b 覆盖了 a;或目标数组长度少 1,越界崩溃
同数组内移位重排:方向决定执行顺序
当 src == dest,就是原地移动。JVM 会根据 srcPos 和 destPos 的大小关系自动选择正向或倒序搬运,避免覆盖:
- 左移(destPos < srcPos):如
System.arraycopy(arr, 4, arr, 2, 5),安全,JVM 正向搬 - 右移(destPos > srcPos):如
System.arraycopy(arr, 2, arr, 5, 5),JVM 自动倒序搬,确保 arr[6] 先搬走再覆盖 arr[2] - 若 srcPos == destPos,等效于什么也不做(length ≠ 0 时);length = 0 合法,可用于边界预检
- 别手动循环模拟——arraycopy 的底层是 memmove 或 SIMD 指令,手写 for 不仅慢,还容易出错
避坑要点:类型、长度、空值一个都不能松
它快,但零容错。五个参数全在运行时校验,错一个就崩:
- 基本类型数组之间完全不兼容:int[] 不能拷到 long[],哪怕只是想“凑合用”也不行
- 引用类型允许子类→父类(String[] → Object[]),但反过来运行时报 ArrayStoreException
- 任何数组为 null,调用前不判空,立刻 NullPointerException
- 小数组(≤ 4 元素)慎用:JNI 开销可能比简单赋值还高
- 泛型方法里别硬套 T[]:类型擦除后无法匹配 System.arraycopy 的签名,编译失败


















