java数组拷贝应按场景选最优方案:system.arraycopy最快但需预分配且长度≥16;arrays.copyof便捷但增加gc压力;小数组(≤8)用for循环更高效;引用类型深拷贝需额外处理。

Java 数组拷贝不是“选哪个写起来顺手”的问题,而是“哪一种在当前场景下真正省内存、不拖慢执行”的判断。关键不在代码行数,而在 JVM 是否能跳过解释层、直接调用底层内存指令(如 memmove 或 SIMD),以及是否引入额外 GC 压力。
System.arraycopy:唯一触发底层指令的原语
它快,但有硬性前提:目标数组必须已分配且非 null;拷贝长度建议 ≥16;源与目标类型严格一致(int[] 不能往 long[] 拷)。
- 满足条件时,JVM 可绕过 Java 解释器,直接调用 C 级内存搬运,实测比 for 循环快 3–5 倍(百万级 int 数组)
- 不满足时(比如 dest 是 null 或 length=3),反而因 JNI 调用开销 + 额外 new 操作,比简单循环还慢
- 支持 src == dest 场景(如数组内元素前移),但需注意拷贝方向:从后往前覆盖,避免未读数据被提前擦除
Arrays.copyOf:开发友好,但隐含一次 new
本质是封装了 System.arraycopy 的语法糖,自动 new 目标数组。适合快速扩容、截取或类型转换(如 int[] → long[]),但代价明确。
- 每次调用都新建数组对象,增加年轻代 GC 频率,尤其在高频小数组拷贝场景(如网络包解析循环)中不可忽视
- 内部调用 System.arraycopy,所以仍受益于底层优化,但多一层堆分配开销
- 若已知目标长度,优先用 System.arraycopy + 复用数组池,而非反复 copyOf
for 循环与 clone():小而确定,大而谨慎
它们不依赖 JVM 底层优化,行为完全可控,适合边界清晰的小规模操作。
- for 循环在 length ≤ 8 时往往最快,无方法调用开销、无 JNI 进入成本,也便于 JIT 提前优化
- clone() 是浅拷贝,对基本类型数组等价于 arraycopy,但对引用类型只复制引用地址;性能介于 for 和 arraycopy 之间,且无法指定起始/长度
- 二者都不触发底层内存指令,也不要求类型匹配,适合调试、原型验证或嵌入式受限环境
真实基准建议:按量级和复用性选策略
不要只看“平均耗时”,要结合内存分配、GC 次数、线程局部性综合判断。
- 单次拷贝、长度固定 > 100:用 System.arraycopy,dest 数组可缓存复用
- 动态长度、需扩容或截断:用 Arrays.copyOf,但避免在 tight loop 中高频调用
- 长度稳定
- 引用类型数组且需深拷贝:以上均不适用,必须配合对象克隆或序列化逻辑
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











