0
点赞
收藏
分享

微信扫一扫

浅拷贝和深拷贝的区别

浅拷贝(Shallow Copy)和深拷贝(Deep Copy)是两种用于复制对象的方法,它们的区别在于新对象如何处理原始对象中的引用类型数据成员。

浅拷贝

浅拷贝会创建一个新对象,这个新对象会复制原始对象的非静态字段。对于值类型的字段(如基本数据类型 int, double 等),它会复制实际的值;而对于引用类型(如数组、对象等),它只复制引用而不复制引用所指向的对象。这意味着原始对象和新对象将共享这些引用类型的数据。

在Java中,可以通过调用 Object 类的 clone() 方法实现浅拷贝,但需要注意的是,只有当类实现了 Cloneable 接口时,clone() 方法才能正常工作,并且可能需要重写 clone() 方法来确保正确的行为。

public class ShallowCopyExample implements Cloneable {
    private int value;
    private Object referenceType;

    // Constructor, getters and setters...

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // 默认是浅拷贝
    }
}

深拷贝

深拷贝不仅会创建一个新的对象,还会递归地复制所有被引用的对象。因此,原始对象和新对象及其内部的所有对象都是完全独立的,修改一个对象不会影响另一个对象。

要实现深拷贝,可以选择以下几种方式之一:

  • 手动复制:在 clone() 方法中手动复制每个引用类型的字段。
  • 使用序列化:如果对象及其包含的所有对象都实现了 Serializable 接口,那么可以使用序列化和反序列化来实现深拷贝。
  • 使用第三方库:一些库如 Apache Commons Lang 提供了 SerializationUtils.clone() 方法来进行深拷贝。

下面是一个使用序列化进行深拷贝的例子:

import java.io.*;

public class DeepCopyExample implements Serializable {
    private int value;
    private Object referenceType;

    // Constructor, getters and setters...

    public DeepCopyExample deepCopy() throws IOException, ClassNotFoundException {
        // 序列化到字节数组输出流
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
             ObjectOutputStream out = new ObjectOutputStream(bos)) {
            out.writeObject(this);

            // 反序列化从字节数组输入流
            try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
                 ObjectInputStream in = new ObjectInputStream(bis)) {
                return (DeepCopyExample) in.readObject();
            }
        }
    }
}

深拷贝比浅拷贝更耗费资源,因为它需要复制更多的数据。此外,深拷贝可能会遇到循环引用的问题,即两个或多个对象互相引用的情况,在这种情况下,简单的递归复制方法会导致无限循环。因此,实现深拷贝时通常需要特别处理这种情况。

举报

相关推荐

0 条评论