Java技巧:深拷贝的两种方式(Java实用技巧:掌握深拷贝的两种高效方法)
原创
一、引言
在Java编程中,对象的拷贝是一个常见的操作。浅拷贝和深拷贝是两种常见的拷贝做法。浅拷贝仅仅复制对象的基本类型字段,而对于引用类型字段,则复制引用而不复制引用的对象本身。深拷贝则会复制对象以及对象引用的所有字段。本文将介绍两种高效的深拷贝方法,帮助大家更好地懂得和掌握深拷贝技巧。
二、深拷贝的两种做法
下面我们将详细介绍两种深拷贝的方法。
2.1 使用序列化与反序列化实现深拷贝
这种做法的核心思想是将对象序列化成字节流,然后再将字节流反序列化成新的对象。以下是具体实现步骤:
- 让对象实现
Serializable
接口,该接口是一个标记接口,不包含任何方法。 - 通过
ObjectOutputStream
将对象序列化到字节流中。 - 通过
ObjectInputStream
从字节流中反序列化出新的对象。
下面是具体代码示例:
import java.io.*;
public class DeepCopyBySerialization implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
// 构造方法、getter和setter省略
public static DeepCopyBySerialization deepCopy(DeepCopyBySerialization obj) throws IOException, ClassNotFoundException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(obj);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (DeepCopyBySerialization) ois.readObject();
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
DeepCopyBySerialization original = new DeepCopyBySerialization(1, "张三");
DeepCopyBySerialization copy = deepCopy(original);
System.out.println("原对象ID: " + original.getId() + ", 名称: " + original.getName());
System.out.println("拷贝对象ID: " + copy.getId() + ", 名称: " + copy.getName());
}
}
2.2 使用构造方法实现深拷贝
这种做法的核心思想是在目标类中提供一个专门的拷贝构造方法,该构造方法接收一个同类对象作为参数,然后逐个复制对象的字段(包括引用类型字段)。以下是具体实现步骤:
- 在目标类中定义一个拷贝构造方法,参数为同类对象。
- 在拷贝构造方法中,对于基本类型字段,直接赋值。
- 对于引用类型字段,创建新的实例,并复制字段值。
下面是具体代码示例:
public class DeepCopyByConstructor {
private int id;
private String name;
private DeepCopyByConstructor otherField;
// 拷贝构造方法
public DeepCopyByConstructor(DeepCopyByConstructor source) {
this.id = source.id;
this.name = source.name;
if (source.otherField != null) {
this.otherField = new DeepCopyByConstructor(source.otherField);
}
}
// 构造方法、getter和setter省略
public static void main(String[] args) {
DeepCopyByConstructor original = new DeepCopyByConstructor(1, "李四", new DeepCopyByConstructor(2, "王五", null));
DeepCopyByConstructor copy = new DeepCopyByConstructor(original);
System.out.println("原对象ID: " + original.getId() + ", 名称: " + original.getName());
System.out.println("拷贝对象ID: " + copy.getId() + ", 名称: " + copy.getName());
System.out.println("原对象otherField名称: " + original.getOtherField().getName());
System.out.println("拷贝对象otherField名称: " + copy.getOtherField().getName());
}
}
三、两种方法的对比
以下是两种深拷贝方法的对比:
- 序列化与反序列化方法:实现单纯,但高效相对较低,且要求对象必须实现
Serializable
接口。 - 构造方法实现:高效较高,但需要手动编写拷贝逻辑,对于错综对象大概较为繁琐。
四、总结
深拷贝是Java编程中一个重要的概念,掌握深拷贝的方法对于避免对象拷贝时出现的问题具有重要意义。本文介绍了两种高效的深拷贝方法:使用序列化与反序列化和使用构造方法。开发者可以采取实际情况选择合适的深拷贝方法,以减成本时间程序的稳定性和性能。