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 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
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() 自带的能力,必须显式编码完成。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










