跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

Java Arrays.copyOf 底层调用 System.arraycopy 的实现

Arrays.copyOf 底层由 JVM JIT 编译器优化为等效于 System.arraycopy 的高效指令,并非源码中显式调用;其具体实现依数组类型、长度由 JVM 动态选择循环、Unsafe 或 native 拷贝。 Java 中
Arrays.copyOf
并不直接“调用”
System.arraycopy
,而是由 JVM 在运行时对特定数组拷贝场景进行高度优化——其中就包括对
Arrays.copyOf
的内联与替换。严格来说,它底层 等效于 (或被 JIT 编译器优化为)
System.arraycopy
的行为,但源码层面并非简单的一行 method call。 为什么 Arrays.copyOf 没有显式写 System.arraycopy? 查看 OpenJDK 源码(如 JDK 17 的
Arrays.java
),会发现
copyOf
方法内部确实调用了类似
newArray[i] = original[i]
的循环逻辑(针对对象数组)或使用了
Unsafe.copyMemory
(在某些重载中)。但关键点在于: JVM 知道
Arrays.copyOf
是基础且高频的操作,HotSpot 的 JIT 编译器会在方法被多次调用后,将其 内联并替换为高效的本地指令 ,最终效果与
System.arraycopy
几乎一致;
System.arraycopy
是一个 native 方法(由 C/C++ 实现),支持内存块级拷贝、CPU 指令优化(如 SIMD)、避免边界检查开销; 直接在 Java 层写循环拷贝效率低、无法利用底层硬件加速,也不安全(比如类型擦除后泛型数组拷贝易出错)。 不同类型的 copyOf 实际执行路径 根据数组类型和长度,JVM 可能选择不同实现策略: 基本类型数组(如 int[]) :绝大多数情况被 JIT 优化为
System.arraycopy
或更底层的
Unsafe.copyMemory
; 引用类型数组(如 String[]) :小数组可能走 Java 循环(含 null 检查),大数组则倾向触发 native 拷贝; 空数组或极小数组(如 length ≤ 4) :可能完全展开为独立赋值指令,避免调用开销。 你可以验证它的等效性 虽然不能直接在源码里看到
System.arraycopy
调用,但可通过以下方式确认其行为一致: Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”; 使用 JMH 基准测试对比
Arrays.copyOf(arr, len)
和手动写的
System.arraycopy
,两者吞吐量几乎无差别; 开启 JVM 参数
-XX:+PrintAssembly
(需 hsdis),观察 JIT 编译后的汇编代码,会发现二者生成的机器指令高度相似; 调试时设断点到
System.arraycopy
,再调用
Arrays.copyOf
,常能命中——说明 JIT 已将其替换为该 native 调用。 开发中该怎么选? 无需纠结底层是否“真正调用”,只需记住: 优先用
Arrays.copyOf
:语义清晰、类型安全、自动处理扩容/截断、JVM 保证最优实现; 避免手写循环拷贝:易错、不可读、无法享受 JIT 优化; 只有在极端可控场景(如嵌入式、确定逃逸分析失效)才考虑裸用
System.arraycopy
,且必须自己做边界和类型检查。 本质上,
Arrays.copyOf
是面向开发者的安全抽象,而
System.arraycopy
是面向 JVM 的性能原语。它们分工明确:一个写在 Java 里,一个藏在 native 中,共同构成高效数组操作的基石。

相关文章