本文目录导读:

在Java中实现深度拷贝(Deep Copy)主要有以下几种方式,我将按照推荐程度和使用场景分别介绍。
序列化方式(最常用)
通过Java序列化机制实现,对象及其所有引用对象都会被复制。
import java.io.*;
public class DeepCopyBySerialization {
// 方法实现
@SuppressWarnings("unchecked")
public static <T extends Serializable> T deepCopy(T obj) {
try {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
oos.flush();
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (T) ois.readObject();
} catch (Exception e) {
throw new RuntimeException("Deep copy failed", e);
}
}
// 测试示例
public static void main(String[] args) {
Address address = new Address("Beijing", "China");
Person original = new Person("张三", 25, address);
Person copied = deepCopy(original);
// 验证深度拷贝 - 修改地址不影响原对象
copied.getAddress().setCity("Shanghai");
System.out.println("Original: " + original); // Beijing
System.out.println("Copied: " + copied); // Shanghai
}
}
// 实体类必须实现Serializable接口
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private Address address;
// getters/setters 省略
// 构造方法、toString方法
}
class Address implements Serializable {
private static final long serialVersionUID = 1L;
private String city;
private String country;
// getters/setters 省略
// 构造方法、toString方法
}
优点:实现简单,自动处理所有引用 缺点:所有类必须实现Serializable,性能相对较差
手动实现Cloneable接口
通过重写clone()方法,手动复制每个属性。
public class DeepCopyByCloneable implements Cloneable {
// 方式一:手动实现clone
static class Person implements Cloneable {
private String name;
private int age;
private Address address;
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Person cloned = (Person) super.clone();
// 手动深度拷贝引用类型
cloned.address = (Address) address.clone();
return cloned;
}
// getters/setters
}
static class Address implements Cloneable {
private String city;
private String country;
public Address(String city, String country) {
this.city = city;
this.country = country;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// getters/setters
}
public static void main(String[] args) throws CloneNotSupportedException {
Address address = new Address("Beijing", "China");
Person original = new Person("张三", 25, address);
Person copied = (Person) original.clone();
// 验证
copied.getAddress().setCity("Shanghai");
System.out.println("Original: " + original); // Beijing
System.out.println("Copied: " + copied); // Shanghai
}
}
优点:性能最好,灵活控制复制逻辑 缺点:需要为每个类实现clone(),开发工作量大
使用JSON序列化
利用JSON库(如Jackson、Gson)实现深度拷贝。
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.BeanUtils;
public class DeepCopyByJSON {
// 使用Jackson
public static <T> T deepCopyByJackson(T obj, Class<T> clazz) {
try {
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(obj);
return mapper.readValue(json, clazz);
} catch (Exception e) {
throw new RuntimeException("JSON deep copy failed", e);
}
}
// 使用Gson
public static <T> T deepCopyByGson(T obj, Class<T> clazz) {
com.google.gson.Gson gson = new com.google.gson.Gson();
String json = gson.toJson(obj);
return gson.fromJson(json, clazz);
}
// 测试
public static void main(String[] args) {
Person person = new Person("李四", 30, new Address("Beijing", "China"));
// Jackson方式
Person jacksonCopy = deepCopyByJackson(person, Person.class);
// Gson方式
Person gsonCopy = deepCopyByGson(person, Person.class);
}
}
优点:不需要实现Serializable,对第三方类也有效 缺点:需要外部依赖,循环引用可能导致问题
复制构造函数方式
通过专门的复制构造函数实现。
public class DeepCopyByConstructor {
static class Person {
private String name;
private int age;
private Address address;
// 普通构造函数
public Person(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}
// 复制构造函数
public Person(Person other) {
this.name = other.name;
this.age = other.age;
// 深度拷贝引用类型
this.address = new Address(other.address);
}
}
static class Address {
private String city;
private String country;
public Address(String city, String country) {
this.city = city;
this.country = country;
}
// 复制构造函数
public Address(Address other) {
this.city = other.city;
this.country = other.country;
}
}
public static void main(String[] args) {
Address address = new Address("Beijing", "China");
Person original = new Person("张三", 25, address);
Person copied = new Person(original);
}
}
使用第三方库
// 使用Apache Commons Lang3
import org.apache.commons.lang3.SerializationUtils;
public class DeepCopyByCommons3 {
public static <T extends Serializable> T deepCopy(T obj) {
return SerializationUtils.clone(obj);
}
}
// 使用Spring BeanUtils(注意:只能深度拷贝第一层)
import org.springframework.beans.BeanUtils;
public class DeepCopyBySpring {
public static <T> T shallowCopy(T source, T target) {
BeanUtils.copyProperties(source, target);
return target;
}
}
推荐使用场景总结
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 简单对象图 | 序列化方式 | 实现简单,一劳永逸 |
| 性能要求高 | 手动Cloneable | 避免反射和序列化开销 |
| 第三方对象 | JSON序列化 | 无需修改原类 |
| 对象结构固定 | 复制构造函数 | 类型安全,可控性强 |
注意事项
- 循环引用:序列化和JSON方式可能无法处理循环引用
- 单例模式:深度拷贝可能会破坏单例
- 不可变对象:不需要深度拷贝,直接引用即可
- 性能选择:如果频繁使用,建议使用手动Cloneable方式
选择哪种方式主要取决于你的具体需求、性能要求和开发成本,对于大多数业务场景,序列化方式是最简单实用的选择。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播