System.arraycopy适用于性能敏感、数组已存在且长度匹配的中等以上规模拷贝,能绕过Java层开销实现高效平移;不适合扩容缩容、类型转换或高频小粒度操作。

直接用 System.arraycopy 不是为了炫技,而是当性能敏感、数组已存在、且拷贝规模中等以上时,它能绕过 Java 层冗余开销,把数据“平移”过去——快得有道理,也快得有条件。
数组已分配,且长度匹配
这是最核心前提。System.arraycopy 不创建新数组,只搬运数据。如果你需要扩容、缩容或生成副本,Arrays.copyOf 更合适——它底层调用 arraycopy,但多包了一层 new 操作;硬套 arraycopy 反而要自己处理目标数组初始化,容易越界或类型错配。
- 适合场景:缓存刷新(覆盖旧 int[])、协议解析切片(从 byte[] 提取 payload)、队列左移(
arraycopy(arr, 1, arr, 0, len-1)) - 不适合场景:想把一个 String[] “转成” ArrayList ——这不是拷贝,是转换,该用 Stream 或构造器
拷贝长度 ≥ 20,且非极端小数据
它的优势随规模放大,但太小反而拖后腿:
- 长度 ≤ 4:JVM 启动 JNI 调用的固定开销可能超过循环本身,for 循环甚至可能被 JIT 栈上分配优化掉
- 长度 20–1000:优势开始稳定,边界检查省了、字节码跳转没了、缓存预取更友好
- 长度 ≥ 10⁵:实测常快 3–5 倍,尤其对
byte[]或int[],逼近 memcpy 硬件带宽
类型兼容,且无需深拷贝
System.arraycopy 是浅拷贝,只复制引用或基础值:
- 允许:
String[] → Object[]、int[] → int[]、自拷贝(重叠安全,类似 memmove) - 禁止:
Object[] → String[](运行时报ArrayStoreException)、int[] → long[](类型不兼容) - 注意:它不递归克隆对象内容,若需深拷贝,得另配序列化或 clone 逻辑
避免高频小粒度调用
别在循环里反复用它拷 1 个元素——JNI 开销会被放大,失去意义:
- 错误写法:
for (int i = 0; i - 正确做法:合并为一次调用
System.arraycopy(src, 0, dst, 0, n),或改用 for 循环 - 若逻辑天然分块(如按 CPU 核数切分 handler 列表),再用
arraycopy批量复制子段
不复杂但容易忽略:日常开发优先选 Arrays.copyOf,它安全、语义清晰;只有当你明确控制目标数组生命周期、追求极致吞吐、且拷贝规模可观时,才裸调 System.arraycopy。


















