深入JAVA对象深度克隆的详解

深入JAVA对象深度克隆的详解

对象深度克隆是指克隆一个对象及其子对象,同时新对象与原对象是互不干扰的,对新对象的任何修改都不会影响原对象。在Java中,实现对象深克隆通常使用“序列化”和“反序列化”技术。本篇文章将详细讲解如何实现Java对象的深度克隆。

实现Java对象深度克隆

方法一:序列化与反序列化实现克隆

序列化对象可以用ObjectOutputStream实现,创建一个ByteArrayOutputStream字节流,将对象写入字节流,再从字节流中读取对象信息并反序列化为原对象。

public static Object deepClone(Object obj) throws IOException, ClassNotFoundException {
    ObjectOutputStream oo = null;
    ObjectInputStream oi = null;
    try {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        oo = new ObjectOutputStream(bo);
        oo.writeObject(obj);
        oi = new ObjectInputStream(new ByteArrayInputStream(bo.toByteArray()));
        return oi.readObject();
    } finally {
        if (oo != null) {
            oo.close();
        }
        if (oi != null) {
            oi.close();
        }
    }
}

方法二:递归实现克隆

定义一个方法,遍历对象及其子对象,并重构克隆对象,最终返回新的对象。

public static Object deepClone(Object obj) {
    if (obj == null) {
        return null;
    }
    Object result = null;
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(obj);
        oos.close();
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        result = ois.readObject();
        ois.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

示例说明

下面我们通过一个示例说明深度克隆方法的使用:

public class Person implements Serializable {
    private String name;
    private Address address;

    public Person(String name, Address address) {
        this.name = name;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public Address getAddress() {
        return address;
    }
}

public class Address implements Serializable {
    private String province;
    private String city;

    public Address(String province, String city) {
        this.province = province;
        this.city = city;
    }

    public String getProvince() {
        return province;
    }

    public String getCity() {
        return city;
    }
}

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Address address = new Address("广东省", "深圳市");
        Person person1 = new Person("小明", address);
        Person person2 = (Person) deepClone(person1);
        System.out.println(person1.getName() + "," + person1.getAddress().getProvince() + "," + person1.getAddress().getCity());
        System.out.println(person2.getName() + "," + person2.getAddress().getProvince() + "," + person2.getAddress().getCity());
        address.setCity("广州市");
        System.out.println(person1.getName() + "," + person1.getAddress().getProvince() + "," + person1.getAddress().getCity());
        System.out.println(person2.getName() + "," + person2.getAddress().getProvince() + "," + person2.getAddress().getCity());
    }

    public static Object deepClone(Object obj) throws IOException, ClassNotFoundException {
        ObjectOutputStream oo = null;
        ObjectInputStream oi = null;
        try {
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            oo = new ObjectOutputStream(bo);
            oo.writeObject(obj);
            oi = new ObjectInputStream(new ByteArrayInputStream(bo.toByteArray()));
            return oi.readObject();
        } finally {
            if (oo != null) {
                oo.close();
            }
            if (oi != null) {
                oi.close();
            }
        }
    }
}

以上示例代码中,我们定义了Person类和Address类,Person对象包含Address对象。deepClone方法实现序列化与反序列化以达到深度克隆的效果。在测试中,我们先克隆一个person1对象,并打印出person1和person2的地址信息,接着改变address的城市信息,并再次打印两个对象的地址信息。可以看到,address对象被改变,但person1和person2的地址信息保持不变,这说明克隆是成功的,深度克隆不会影响原对象。

阅读剩余 64%

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入JAVA对象深度克隆的详解 - Python技术站

(0)
上一篇 2023年5月26日
合作推广
合作推广
分享本页
返回顶部