System.arraycopy是JVM层面的内存块搬运指令,不创建数组、不装箱、不校验元素值,仅按参数精确搬移内存;其五个参数src、srcPos、dest、destPos、length各司其职,任一错误即抛异常。

System.arraycopy 不是复制函数,而是 JVM 层面的内存块搬运指令。它不创建数组、不装箱、不校验元素值,只按参数精确搬移内存;用对了,一行代码完成高效片段搬运;用错了,还没开始搬就抛异常——NullPointerException、ArrayIndexOutOfBoundsException、ArrayStoreException 都可能立刻发生。
五个参数各管什么,一个都不能错
调用格式固定:System.arraycopy(src, srcPos, dest, destPos, length)
- src:源数组,不能为空,否则直接抛 NullPointerException
- srcPos:读取起点,必须 ≥ 0 且 ≤ src.length;若 srcPos + length > src.length,立即抛 ArrayIndexOutOfBoundsException
- dest:目标数组,必须已 new 出来,不能为 null;组件类型需兼容(如 String[] 可往 Object[] 拷,但 int[] 不能往 long[] 拷)
- destPos:写入起点,必须 ≥ 0;且 destPos + length ≤ dest.length,否则越界
- length:拷几个元素,可为 0(合法空操作,常用于预检),但不能为负(否则抛 NegativeArraySizeException)
截取、拼接、原地移位,全靠参数算准
这不是语法糖,是两步地址搬运,每一步都得算准:
- 截取一段:比如从 byte[] src 中取 offset=100 开始的 1024 字节 → System.arraycopy(src, 100, dest, 0, 1024),前提是 100 + 1024 ≤ src.length;dest 必须提前 new 好,长度至少为 1024
- 拼接两个数组:int[] a 和 int[] b 合成 result → 先 new int[a.length + b.length];再分两次:System.arraycopy(a, 0, result, 0, a.length);System.arraycopy(b, 0, result, a.length, b.length)
- 同一数组内移位:JVM 自动判断方向。src == dest 时,destPos > srcPos(右移)→ 倒序搬;destPos
类型兼容性与内存一致性,运行时才校验
编译器不拦,JVM 执行时才检查:
立即学习“Java免费学习笔记(深入)”;
- int[] 往 long[] 拷 → 运行时报 ArrayStoreException
- String[] 往 Object[] 拷 → 合法(协变允许)
- Object[] 往 String[] 拷 → 报 ArrayStoreException
- Integer[] 往 int[] 拷 → 不支持,装箱/拆箱不在 arraycopy 路径内
- 所有拷贝都是浅拷贝:对象数组只复制引用,修改对象内容会同时影响源和目标
性能关键:什么时候用,怎么用才真快
它快,但只在满足条件时才真正快:
- 长度
- 长度 ≥ 256:JIT 更易向量化,推荐启用
- 目标数组必须提前分配好,不能靠 arraycopy 分配或扩容
- 基本类型数组(byte[]、int[])最快;对象数组拷引用也快,但无内存对齐加速
- 避免小块跨 cache line 搬运;固定结构协议中,偏移量可写死提升 JIT 优化机会


















