system.arraycopy在对象数组克隆中性能最优,因其绕过java层重复校验、直接内存搬运并被jit深度优化;而clone()有额外分配开销,for循环则受多次边界检查和类型校验拖累。

System.arraycopy 在对象数组克隆中性能明显优于 clone() 和手动循环,核心优势在于绕过 Java 层重复校验、直接内存搬运,并被 JIT 深度优化。
为什么 object[] 用 System.arraycopy 更快
对象数组(如 String[]、User[])的拷贝不涉及元素内容深复制,只复制引用地址。此时性能差异主要来自 JVM 执行路径:
- System.arraycopy:一次性完成源/目标非空、索引范围、类型兼容性(如 Object[] ← String[] 合法)等校验,随后调用 native 内存拷贝函数,无字节码循环开销,支持 SIMD 加速
- clone():虽也是 native 方法,但需先创建新数组对象(额外分配开销),再内部调用 arraycopy —— 多一层方法跳转和对象初始化逻辑
- for 循环:每次 a[i] 读取 + b[i] = x 写入都触发两次边界检查(源索引、目标索引)+ 类型运行时校验(如确保赋值给 String[] 的确实是 String 实例),JIT 难以完全向量化
实测典型场景下的差距
以 10 万个 String 元素的数组为例(JDK 17,64 位 HotSpot):
- System.arraycopy:约 0.04–0.06 ms(复用已分配目标数组)
- array.clone():约 0.15–0.22 ms(含新数组分配 + 内部拷贝)
- for 循环(缓存 length):约 0.28–0.45 ms(受分支预测与边界检查拖累)
- Arrays.copyOf:约 0.18–0.25 ms(本质是 new 数组 + arraycopy,多一次分配)
差距随长度扩大而加剧;超过 100 万元素时,arraycopy 可达 clone 的 4–5 倍速度。
对象数组使用 System.arraycopy 的关键注意事项
它高效但有明确前提,用错反而引入异常或语义错误:
- 目标数组必须预先创建,且类型兼容:String[] 可拷入 Object[],但不能拷入 Integer[];否则抛 ArrayStoreException
- 支持子区间拷贝:比如只复制前 1000 个引用,无需新建全长数组再截断
- 自拷贝安全:src == dest 时自动处理重叠(类似 memmove),不用区分前后拷贝方向
- 不触发 GC 压力的关键:避免在高频循环里反复 new 目标数组;应复用缓冲区,仅用 arraycopy 填充数据
何时该选 clone() 或其他方式
并非所有场景都适合 arraycopy,简洁性和语义清晰有时更重要:
- 只需快速获得完整副本,且目标类型明确(如 List
转 User[] 后立即 clone)→ arr.clone() 更直观 - 需要扩容或动态长度 → Arrays.copyOf(arr, newSize) 封装了分配+拷贝,语义清晰
- 要深拷贝对象内容(非仅引用)→ arraycopy 和 clone 都不适用,需遍历并调用每个元素的 clone 或构造新实例
- 小数组(≤ 64 元素)且代码可读性优先 → 差异微乎其微,选最易维护的写法











