clone()对基本类型数组是深拷贝,元素值独立复制;对对象数组是浅拷贝,仅复制引用地址,修改对象属性会影响原数组;system.arraycopy()和arrays.copyof()均为浅拷贝,底层均调用jvm原生内存搬运。

Java 数组克隆不是“复制地址”,而是创建独立内存块的过程;但是否真正隔离原始数据,取决于数组类型和克隆方式。关键在于区分基本类型与对象数组的行为差异,以及各方法在底层是否触发实际内存拷贝。
clone() 方法:最简捷但有隐含规则
所有数组都继承 Object.clone(),调用时无需实现 Cloneable 接口(JVM 对数组做了特殊支持)。对 int[]、double[]、boolean[] 等基本类型数组,clone() 是深拷贝:新数组拥有全新堆内存,元素值逐个复制,修改互不影响。
对 String[]、Person[] 等引用类型数组,clone() 是浅拷贝:新数组本身是新对象,但每个元素仍指向原对象。这意味着:
- 修改 clonedArray[i] = new String("x") —— 安全,只改引用
- 修改 clonedArray[0].setName("Alice") —— 原 originalArray[0] 同步变更
System.arraycopy():可控、高效、需手动准备目标数组
这是 JVM 内部用本地代码(C)实现的拷贝指令,性能最优,常用于高频或大数据量场景。它不关心类型,只按字节/引用粒度搬运数据。
使用前提:必须提前创建好目标数组(如 int[] dest = new int[src.length]),否则抛 NullPointerException。
典型用途包括:
- 数组扩容时迁移旧数据
- 滑动窗口中复用缓冲区
- Android 中复制 OpenGL 顶点坐标 float[],避免 UI 线程误写
Arrays.copyOf() 及其变体:语义清晰,适合日常开发
Arrays.copyOf(arr, len) 封装了 arraycopy,自动新建数组并完成拷贝,还支持长度伸缩:
- len > arr.length → 新数组后缀补默认值(0 / null)
- len
Arrays.copyOfRange(arr, from, to) 更进一步,专为切片设计(to 不包含),底层同样调用 arraycopy,但起始/结束位置由参数控制,避免手算偏移。
对象数组深拷贝:不能只靠 clone()
当需要完全隔离对象数组(如 Person[]),必须对每个元素单独深拷贝。常见做法有:
- 若 Person 实现 Cloneable:循环调用 cloned[i] = (Person) p[i].clone()
- 使用构造函数复制:new Person(p[i].getName(), p[i].getAge())
- 借助序列化(适用于可序列化类):通过 ByteArrayOutputStream + ObjectInputStream 实现递归深拷贝
注意:反射或 JSON 序列化(如 Gson.toJson().fromJson())虽可行,但有运行时开销与兼容性风险,生产环境慎用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











