本文目录导读:

- 实现 Cloneable 接口(浅克隆)
- 手动深克隆(重写clone方法)
- 使用拷贝构造器
- 使用序列化(最彻底的深克隆)
- 使用第三方库(推荐)
- 使用Java Records(Java 16+)
- 实际案例:完整深克隆示例
- 推荐方案
在Java中克隆对象数据有多种方式,我将为你详细介绍几种主流方法:
实现 Cloneable 接口(浅克隆)
public class Student implements Cloneable {
private String name;
private int age;
private Address address; // 引用类型
// 构造器、getter/setter省略
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // 默认浅克隆
}
}
// 使用
Student s1 = new Student("张三", 20, new Address("北京"));
Student s2 = (Student) s1.clone(); // 浅克隆
缺点:引用类型字段只复制引用,不复制对象本身。
手动深克隆(重写clone方法)
@Override
protected Object clone() throws CloneNotSupportedException {
// 先浅克隆
Student cloned = (Student) super.clone();
// 手动深克隆引用类型
if (this.address != null) {
cloned.address = (Address) this.address.clone();
}
return cloned;
}
需要确保所有引用类型也实现了Cloneable接口。
使用拷贝构造器
public class Student {
private String name;
private int age;
private Address address;
// 拷贝构造器
public Student(Student other) {
this.name = other.name;
this.age = other.age;
// 深克隆引用类型
this.address = new Address(other.address); // Address也需要拷贝构造器
}
}
// 使用
Student s2 = new Student(s1);
使用序列化(最彻底的深克隆)
import java.io.*;
public class CloneUtil {
@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepClone(T obj) {
try {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
} catch (Exception e) {
throw new RuntimeException("克隆失败", e);
}
}
}
// 使用
Student s2 = CloneUtil.deepClone(s1);
要求:所有类必须实现Serializable接口。
使用第三方库(推荐)
Apache Commons Lang3
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
// 需要实现Serializable Student s2 = SerializationUtils.clone(s1);
使用JSON序列化(Jackson/Gson)
// Jackson方式 ObjectMapper mapper = new ObjectMapper(); Student s2 = mapper.readValue(mapper.writeValueAsString(s1), Student.class); // Gson方式 Gson gson = new Gson(); Student s2 = gson.fromJson(gson.toJson(s1), Student.class);
使用Java Records(Java 16+)
Record类型自动提供了复制方法:
public record Student(String name, int age, Address address) {
// 自动生成:构造器、equals、hashCode、toString
}
// 使用with修改某些字段
Student s2 = new Student("张三", 20, new Address("北京"));
Student s3 = new Student(s2.name(), s2.age(), new Address("上海"));
实际案例:完整深克隆示例
import java.io.*;
class Address implements Serializable {
private static final long serialVersionUID = 1L;
private String city;
public Address(String city) {
this.city = city;
}
// getter/setter...
}
class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private Address address;
private Salary salary; // 另一个引用类型
// 使用序列化实现深克隆
public Employee deepClone() {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Employee) ois.readObject();
} catch (Exception e) {
throw new RuntimeException("克隆失败", e);
}
}
}
// 测试
public class TestClone {
public static void main(String[] args) {
Employee e1 = new Employee("张三", new Address("北京"), new Salary(10000));
Employee e2 = e1.deepClone();
// 修改e2的地址,不会影响e1
e2.getAddress().setCity("上海");
System.out.println(e1.getAddress().getCity()); // 输出:北京(深克隆成功)
}
}
推荐方案
- 简单对象:使用拷贝构造器
- 复杂对象图:使用序列化方式
- 性能要求高:手动实现深克隆
- 企业级应用:使用Apache Commons或JSON序列化
选择哪种方式取决于你的具体需求,包括性能要求、对象复杂度、是否需要完全独立等。