system.arraycopy 是 java 最高效的数组拷贝原语,但仅做内存块复制:基本类型数组值拷贝、完全隔离;引用类型数组浅拷贝、共享对象实例;运行时严格校验索引与类型,适合大数据量批量拷贝。

System.arraycopy 是 Java 中最高效的数组拷贝原语,但它不区分数据语义——只做内存块复制。真正影响行为的,是数组元素本身的类型:基本类型直接拷贝值,引用类型只拷贝地址。理解这点,才能避免“改了目标数组,源数组也跟着变”的意外。
基本类型数组:值拷贝,完全隔离
int[]、double[]、boolean[] 等基本类型数组,arraycopy 复制的是每个元素的真实数值。源数组与目标数组在内存中互不干扰。
- 修改 src[0] 不会影响 dest[0],反之亦然
- 即使 src 和 dest 是同一数组(如实现原地移动),只要索引不重叠,也能安全使用
- 典型场景:快速填充缓冲区、滚动日志数组、算法中临时置换子段
引用类型数组:浅拷贝,共享对象实例
String[]、Person[]、List[] 等引用类型数组,arraycopy 复制的是每个元素存储的**对象引用地址**,而非对象本身。结果是两个数组指向同一组堆内存中的对象。
- 若 Person 对象可变(比如有 public setAge()),修改 persons2[0].setAge(99),persons[0].getAge() 也会变成 99
- String 是例外:因不可变,修改 persons2[0] = "new" 只会替换引用,不影响原数组——但这是赋值行为,不是 arraycopy 的副作用
- 这不是 bug,而是设计使然;如需独立副本,必须手动对每个元素做深拷贝(如调用 clone() 或构造新对象)
参数使用要点:越界与类型检查
arraycopy 在运行时做严格校验,常见错误有两类:
- 索引越界:srcPos + length > src.length 或 destPos + length > dest.length → 抛出 ArrayIndexOutOfBoundsException
- 类型不兼容:src 和 dest 元素类型不能协变(如 Object[] ← String[] 合法,但 String[] ← Object[] 非法)→ 抛出 ArrayStoreException
- 推荐做法:拷贝前用 Math.min(src.length, dest.length) 控制 length,或封装成带边界保护的工具方法
性能优势与适用边界
相比 for 循环或 Arrays.copyOf,arraycopy 是 JVM 内置的 native 方法(底层常调用 memcpy),在大数据量时优势明显。
- 适合批量拷贝(>100 元素)、高频调用(如网络包解析、图像像素搬运)
- 不适合需要深拷贝或条件过滤的场景——它不做逻辑判断,只做裸数据搬运
- 多维数组?注意:它只处理一维。拷贝二维数组需嵌套调用,或配合 clone()











