System.arraycopy是JVM native方法,无Java源码实现,底层由C/C++编写并调用memcpy/memmove等系统指令;参数在校验失败时立即抛异常且不执行拷贝;重叠时自动选择正向或倒序搬运以保证安全;其性能优势源于绕过字节码解释、边界检查及栈帧开销,直接进行硬件级内存块搬运。

System.arraycopy 不是 Java 层可读源码的方法,它没有 Java 源代码实现——它是 JVM 的 native 方法,底层由 C/C++ 编写,直接调用操作系统级内存指令(如 memcpy 或 memmove),因此在 OpenJDK 源码中只看到一个空壳声明:
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
真正逻辑藏在 JVM 实现里(例如 OpenJDK 的 hotspot/src/share/vm/prims/jvm.cpp 及平台相关汇编),开发者无法修改或调试其内部,但可通过行为反推机制并安全高效使用。
参数校验:JVM 启动即拦截,不进方法体就失败
调用前 JVM 会原子化检查全部五参数,任一违规立即抛异常,**不执行任何拷贝**:
立即学习“Java免费学习笔记(深入)”;
- src 或 dest 为 null → NullPointerException
- srcPos、destPos、length 任一小于 0 → IndexOutOfBoundsException
- srcPos + length > src.length 或 destPos + length > dest.length → IndexOutOfBoundsException
- src 元素类型无法存入 dest(如 String[] → Integer[])→ ArrayStoreException
注意:这些检查发生在 native 入口前,不是 Java 层循环中逐个判断,因此开销固定且极低。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
搬运策略:重叠时自动选向,靠的是 memmove 而非 memcpy
当 src == dest(原地移动),JVM 不会简单按顺序从左到右复制——它识别重叠区域并自动切换搬运方向:
- destPos
- destPos > srcPos(右移,如把索引 1 开始的元素移到索引 4)→ 倒序拷贝,避免覆盖未读数据
- 这等效于 C 标准库的
memmove,而非memcpy;手写 for 循环若没处理方向,必然出错
性能本质:绕过 Java 字节码与边界检查
它的快不是“优化出来的”,而是架构级规避:
- 跳过 JIT 编译器对每次数组访问的隐式范围检查(for 循环中每个
a[i]都要查) - 不生成中间对象,不触发 GC,不装箱/拆箱(对基本类型尤其关键)
- 大块数据直接走 CPU 的 SIMD 指令或 DMA 通道,吞吐接近内存带宽极限
- 实测:拷贝 100 万个 int,arraycopy 比 for 循环快 3~5 倍;长度 ≤ 16 时,for 反而略优(JNI 调用成本占比上升)
泛型与类型擦除下的真实行为
尽管 ArrayList 等泛型类大量使用它,但 arraycopy 本身完全无视泛型:
- 声明为
Object[]底层数组?没问题,它只搬引用地址 - 把 String[] 拷到 Object[]?允许,因 String 是 Object 子类
- 把 Object[] 拷到 String[]?运行时报 ArrayStoreException——JVM 在 copy 过程中逐个检查元素实际类型
- 它不做转型,不调用 equals/hashCode,不触发任何对象方法,纯内存平移
典型误用场景与修复
实战中最容易踩坑的不是不会用,而是“以为它会做它不做的事”:
- 误以为能自动扩容:arraycopy 不 new 数组,dest 必须提前分配好,否则 IndexOutOfBoundsException
- 误写 destPos 导致覆盖:拼接两个数组时,第二段 destPos 写成 0 而非 first.length,结果后者全盖前者
- 忽略 length 单位是元素个数:对 byte[] 误传字节数当作 length,却用 char[] 接收,类型不匹配当场崩
- 多线程共用 dest 数组无同步:并发写同一 dest 区域,出现数据撕裂,必须加锁或改用不可变引用替换
它不是万能胶,而是手术刀——精准、锋利、不容误差。理解它不做什么,比知道它做什么更重要。

















