实战教程:使用Java函数实现深拷贝和浅拷贝功能
发布时间:2023-06-18 07:14:03
深拷贝和浅拷贝是对象复制的两种方式,深拷贝会克隆对象和其所有属性,即使属性是引用类型也会复制它的副本,而浅拷贝则只复制对象本身和其引用类型的引用,不会复制引用类型的实际内容。在Java中,我们可以通过实现clone()方法或使用序列化来实现深拷贝和浅拷贝功能。
1. 实现深拷贝
实现深拷贝的方法有多种,例如:
(1)通过实现Serializable接口来进行序列化和反序列化
该方法需要对象及其引用类型都实现Serializable接口。具体实现可以通过将对象序列化为byte数组,然后反序列化为新对象的方式来克隆一个完全独立的拷贝。示例如下:
import java.io.*;
public class DeepCopyExample implements Serializable {
private int value;
private DeepCopyObject obj;
public DeepCopyExample(int value, DeepCopyObject obj) {
this.value = value;
this.obj = obj;
}
public DeepCopyExample deepCopy() throws IOException, ClassNotFoundException {
//将对象序列化为byte数组
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(this);
//反序列化byte数组为新对象
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
return (DeepCopyExample) ois.readObject();
}
public static void main(String[] args) throws Exception {
DeepCopyObject obj = new DeepCopyObject("Original");
DeepCopyExample original = new DeepCopyExample(1, obj);
DeepCopyExample deepCopy = original.deepCopy();
System.out.println(original == deepCopy); //false
System.out.println(original.obj == deepCopy.obj); //false
}
}
class DeepCopyObject implements Serializable {
private String name;
public DeepCopyObject(String name) {
this.name = name;
}
}
(2)通过递归复制对象及其属性来实现深度复制
该方法需要我们手动递归复制对象及其属性,将所有引用类型的属性也进行深拷贝。示例如下:
public class DeepCopyExample2 implements Cloneable {
private int value;
private DeepCopyObject2 obj;
public DeepCopyExample2(int value, DeepCopyObject2 obj) {
this.value = value;
this.obj = obj;
}
public DeepCopyExample2 deepCopy() throws CloneNotSupportedException {
DeepCopyExample2 copy = (DeepCopyExample2) super.clone();
copy.obj = obj.deepCopy();
return copy;
}
public static void main(String[] args) throws Exception {
DeepCopyObject2 obj = new DeepCopyObject2("Original");
DeepCopyExample2 original = new DeepCopyExample2(1, obj);
DeepCopyExample2 deepCopy = original.deepCopy();
System.out.println(original == deepCopy); //false
System.out.println(original.obj == deepCopy.obj); //false
}
}
class DeepCopyObject2 implements Cloneable {
private String name;
public DeepCopyObject2(String name) {
this.name = name;
}
public DeepCopyObject2 deepCopy() throws CloneNotSupportedException {
return (DeepCopyObject2) super.clone();
}
}
2. 实现浅拷贝
Java中默认的clone()方法实现的是浅拷贝,即只复制了对象本身和其引用类型的引用,不会复制其实际内容。示例如下:
public class ShallowCopyExample implements Cloneable {
private int value;
private DeepCopyObject obj;
public ShallowCopyExample(int value, DeepCopyObject obj) {
this.value = value;
this.obj = obj;
}
public ShallowCopyExample clone() throws CloneNotSupportedException {
return (ShallowCopyExample) super.clone();
}
public static void main(String[] args) throws Exception {
DeepCopyObject obj = new DeepCopyObject("Original");
ShallowCopyExample original = new ShallowCopyExample(1, obj);
ShallowCopyExample shallowCopy = original.clone();
System.out.println(original == shallowCopy); //false
System.out.println(original.obj == shallowCopy.obj); //true
}
}
class DeepCopyObject3 implements Cloneable {
private String name;
public DeepCopyObject3(String name) {
this.name = name;
}
}
深拷贝和浅拷贝各有优劣,需要根据具体情况选择使用。我们可以通过实现Serializable接口或手动递归复制对象及其属性来实现深拷贝,使用默认的clone()方法实现浅拷贝。需要注意的是,在使用克隆方法复制对象时,对象本身及其属性也需要实现Cloneable接口,否则会抛出CloneNotSupportedException异常。
