java中数组的clone()是浅拷贝,仅复制数组容器和元素引用;要实现深拷贝,需类实现cloneable并重写clone()递归克隆引用字段,再配合遍历调用元素clone()。

Java 中用 clone() 备份对象数组,本身不是深拷贝——它只复制数组容器和元素引用,不重建对象实例。想靠它实现真正隔离修改,必须配合类自身的 clone() 实现,否则改副本等于改原数据。
对象数组 clone() 的真实行为
调用 people.clone() 会生成一个新数组,但数组里每个 Person 元素仍指向堆中同一个对象。也就是说:
- 数组地址不同(
copy != original),但元素地址相同 -
copy[0].setName("X")会同步影响original[0] - 基本类型数组(如
int[])不受此限,因为值被完整复制
让 clone() 支持深拷贝的关键:类要可克隆且正确实现
仅调用数组的 clone() 不够,每个元素也得能独立复制。前提是:
- 目标类(如
Person)实现Cloneable接口 - 重写
clone()方法,并对所有可变引用字段递归克隆(例如address.clone()) - 避免直接返回
super.clone()后不做处理——那仍是浅拷贝
示例片段:
String name;
Address address;
public Person clone() {
try {
Person p = (Person) super.clone();
p.address = this.address != null ? this.address.clone() : null;
return p;
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
组合使用:数组 clone + 元素 clone 才算完整深拷贝
有了可克隆的类,才能安全组合出真正的深拷贝逻辑:
- 先用
original.clone()创建新数组容器 - 再遍历,对每个元素调用其
clone()方法 - 避免直接赋值或依赖默认行为
代码示意:
Person[] deepCopy = original.clone();for (int i = 0; i if (deepCopy[i] != null) {
deepCopy[i] = deepCopy[i].clone();
}
}
替代方案对比:什么时候别硬刚 clone()
如果类没设计好 clone(),或含复杂嵌套、集合、循环引用,强行补 clone() 容易出错。可考虑:
-
复制构造函数:简单干净,适合结构稳定的小对象(
new Person(p)) - JSON 序列化:Gson/Fastjson 一行转 JSON 再反序列化,适合 DTO 场景
-
序列化/反序列化:通用但慢,还要所有类实现
Serializable
不复杂但容易忽略:深拷贝成败不在数组怎么拷,而在每个对象是否真正新生。从设计阶段就支持克隆,比后期打补丁更可靠。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











