Java中Object.clone()默认是浅拷贝,因为它仅复制字段值(含引用地址)而不递归复制引用对象;需实现Cloneable接口、重写clone()并调用super.clone();深拷贝须手动处理引用字段。

Java 中 Object.clone() 方法默认实现的是**浅拷贝**,它不会递归复制对象内部引用的其他对象,而是直接复制引用地址。
为什么 clone 是浅拷贝?
clone() 的默认行为由 JVM 提供:它会为当前对象分配一块新内存,然后把原对象各字段的值(包括基本类型值和引用类型地址)逐字节复制过去。对引用类型字段,复制的是“指向对象的指针”,不是被引用对象本身的新副本。
例如:
class Person {
String name;
Address address; // 引用类型
Person(String name, Address addr) {
this.name = name;
this.address = addr;
}
}
class Address { String city; Address(String c) { this.city = c; } }
Person p1 = new Person("Alice", new Address("Beijing"));
Person p2 = (Person) p1.clone(); // 浅拷贝
p2.name = "Bob"; // 修改基本类型字段 → p1.name 不变
p2.address.city = "Shanghai"; // 修改引用对象内容 → p1.address.city 也变成 "Shanghai"
要使用 clone() 必须满足哪些条件?
- 类必须实现 Cloneable 接口(空接口,仅作标记;不实现会抛
CloneNotSupportedException) - 需重写
public Object clone()方法,并调用super.clone() - 建议将返回类型改为具体类类型(利用协变返回类型),避免强制转型
如何正确重写 clone() 实现浅拷贝?
标准写法示例:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
public class Person implements Cloneable {
private String name;
private Address address;
@Override
public Person clone() {
try {
return (Person) super.clone(); // 调用 Object.clone()
} catch (CloneNotSupportedException e) {
throw new AssertionError(); // Cloneable 已实现,理论上不会发生
}
}
}
注意:super.clone() 返回的是新对象,其字段值与原对象一致——这就是浅拷贝的本质。
什么时候需要深拷贝?怎么配合 clone 实现?
当对象包含可变的引用类型字段(如数组、集合、自定义对象),且你希望副本完全独立时,需手动处理深拷贝。
- 在重写的
clone()方法中,对每个引用字段单独调用其clone()方法(前提是该类也支持克隆) - 或者用其他方式重建引用对象,例如:
new Address(this.address.city)或this.address.clone() - 若引用类不支持 clone(如
ArrayList),可调用其构造器或new ArrayList(originalList)
深拷贝不是 Object.clone() 自带的能力,必须显式编码完成。

















