欢迎访问宙启技术站
智能推送

实战教程:使用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异常。