java中object类的clone()默认只支持浅拷贝,即基本类型字段值复制、引用类型仅复制地址;深拷贝需手动重写clone()逐层克隆引用字段,或通过序列化/反序列化实现。

Java 中 Object 类的 clone() 方法默认只支持**浅拷贝**,且不能直接用于深拷贝;要实现深拷贝,必须手动重写 clone() 并逐层克隆引用类型字段。
浅拷贝:Object.clone() 的默认行为
Object 类中定义了受保护的 clone() 方法,它会创建一个新对象,并将原对象的**基本类型字段值直接复制**,而**引用类型字段仅复制引用地址**(即两个对象共享同一堆内存中的对象)。要使用它,类必须实现 Cloneable 接口,否则抛出 CloneNotSupportedException。
示例:
public class Person implements Cloneable {
private String name;
private Address address; // 引用类型
public Person(String name, Address address) {
this.name = name;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 浅拷贝:address 字段指向同一个 Address 实例
}
}
调用后:person1.clone() 得到的新对象与原对象的 name 独立,但 address 是同一实例 —— 修改新对象的 address.city 会影响原对象。
实现深拷贝的两种常用方式
深拷贝要求所有层级的对象都新建实例。Java 没有自动机制,需主动处理引用字段:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
在重写的 clone() 中手动克隆每个引用字段:确保被引用类也支持克隆(实现
Cloneable并重写clone()),然后在父类clone()中调用它们的clone()方法。 -
使用序列化/反序列化(通用但有约束):对象及其所有字段类型都必须实现
Serializable;利用ObjectOutputStream写入字节数组再用ObjectInputStream读回,天然实现深拷贝(因重建了整个对象图)。
手动实现深拷贝(推荐用于可控、结构清晰的场景)
关键点:每个引用字段都要显式调用其 clone() 或构造新实例。
public class Person implements Cloneable {
private String name;
private Address address;
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone(); // 先浅拷贝本层
if (this.address != null) {
cloned.address = (Address) this.address.clone(); // 深拷贝引用字段
}
return cloned;
}
}
class Address implements Cloneable {
private String city;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // String 是不可变类型,浅拷贝安全
}
}
注意:String、包装类等不可变对象可直接浅拷贝;集合类(如 ArrayList)需调用其 clone() 或遍历元素逐个克隆。
序列化方式实现深拷贝(适合复杂嵌套或不想侵入业务类时)
优点是“开箱即用”,缺点是性能较低、要求严格、不支持 transient 或非 Serializable 字段。
public static <t extends serializable> T deepClone(T obj) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis)) {
oos.writeObject(obj);
return (T) ois.readObject();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
</t>
调用:Person copy = deepClone(originalPerson); —— 此时 copy 和 originalPerson 完全独立。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










