【Java面试】java的深拷贝和浅拷贝


在Java中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是对象复制时的两种主要策略。它们的主要区别在于如何处理对象中的引用类型字段。

浅拷贝(Shallow Copy)

浅拷贝只是复制对象的引用,而不是实际的对象。如果对象包含对另一个对象的引用,那么浅拷贝将只复制该引用,而不是引用的对象。因此,原始对象和复制对象将引用相同的对象。

原理分析
  • 对于基本数据类型(byte, short, int, long, float, double, char, boolean),浅拷贝会直接复制值。
  • 对于引用数据类型(类、接口、数组等),浅拷贝会复制引用,而不是引用的对象。
代码示例
public class ShallowCopyExample {
    private int value;
    private Object ref;

    // 构造函数、getter和setter等省略

    @Override
    public ShallowCopyExample clone() {
        try {
            return (ShallowCopyExample) super.clone(); // 使用Object类的clone方法进行浅拷贝
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        ShallowCopyExample original = new ShallowCopyExample();
        original.setValue(10);
        original.setRef(new Object());

        ShallowCopyExample copied = original.clone();

        // 修改原始对象的引用对象
        original.getRef().notify(); // 假设Object类有一个notify方法(实际没有,仅为示例)

        // 复制对象也会受到影响,因为它们引用的是同一个对象
        // 这里只是一个假设的示例,因为Object类没有notify方法
    }
}

深拷贝(Deep Copy)

深拷贝会复制对象及其引用的对象,以及那些对象的引用对象,依此类推,直到没有引用为止。这意味着原始对象和复制对象是完全独立的,对其中一个的修改不会影响另一个。

原理分析
  • 对于基本数据类型,深拷贝会直接复制值。
  • 对于引用数据类型,深拷贝会递归地复制对象及其引用的所有对象。
代码示例

由于Java没有直接提供深拷贝的方法,我们通常需要手动实现或使用序列化(如果对象实现了Serializable接口)或其他库(如Apache Commons Lang的SerializationUtils)。

以下是一个使用序列化和反序列化实现深拷贝的示例:
下滑查看解决方法

import java.io.*;

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

    // 构造函数、getter和setter等省略

    public DeepCopyExample deepCopy() {
        try {
            // 写入对象到字节数组输出流(即序列化)
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            // 从字节数组输入流读取对象(即反序列化)
            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (DeepCopyExample) ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        DeepCopyExample original = new DeepCopyExample();
        original.setValue(10);
        original.setRef(new Object());

        DeepCopyExample copied = original.deepCopy();

        // 修改原始对象的引用对象不会影响复制对象
        // 因为它们是完全独立的对象
    }
}

注意:使用序列化进行深拷贝时,必须确保对象及其所有引用的对象都实现了Serializable接口,并且没有使用任何不支持序列化的字段(如瞬态字段)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值