【java面试】java深拷贝和浅拷贝的区别


在Java中,深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是对象复制时两种不同的策略,它们的主要区别在于复制的深度和对象之间的引用关系。

浅拷贝(Shallow Copy)

  • 浅拷贝仅仅复制对象的引用,而不是对象本身。换句话说,它创建了一个新的对象,并将原始对象的字段值复制到新对象中。但是,如果字段是引用类型(如数组、集合或其他对象),则浅拷贝会复制这些引用,而不是引用的对象。因此,原始对象及其副本将引用相同的对象。
  • 在Java中,通过实现Cloneable接口并重写clone()方法或使用拷贝构造函数(copy constructor)可以实现浅拷贝。
  • 如果在复制之后修改了原始对象或其引用对象,则副本可能也会受到影响,因为它们引用的是相同的对象。

深拷贝(Deep Copy)

  • 深拷贝会创建一个全新的对象,并递归地复制该对象及其所有子对象。它创建新的引用对象,并将它们复制到新对象中。这样,原始对象和副本对象之间没有引用关系。
  • 在Java中,实现深拷贝通常比较复杂,因为需要手动编写代码来复制对象的所有字段,包括引用类型的字段。这可能需要使用序列化和反序列化、使用第三方库(如Apache Commons Lang的SerializationUtils)或手动编写递归复制逻辑。
  • 深拷贝可以确保原始对象和副本对象是完全独立的。对原始对象或其引用对象的任何修改都不会影响副本对象。

示例

下滑查看解决方法

假设我们有一个Person类,它有一个引用类型的字段address

class Person implements Cloneable {
    private String name;
    private Address address;

    // 构造函数、getter和setter方法...

    @Override
    protected Person clone() throws CloneNotSupportedException {
        Person person = (Person) super.clone(); // 浅拷贝
        return person;
    }

    // 假设Address类也实现了Cloneable接口并重写了clone方法
}

class Address implements Cloneable {
    private String street;
    private String city;

    // 构造函数、getter和setter方法...

    @Override
    protected Address clone() throws CloneNotSupportedException {
        return (Address) super.clone(); // 浅拷贝
    }
}

如果直接调用Person对象的clone()方法进行浅拷贝,那么得到的副本和原始对象将引用相同的Address对象。为了实现深拷贝,我们需要修改Person类的clone()方法,以确保它也复制address字段:

@Override
protected Person clone() throws CloneNotSupportedException {
    Person person = (Person) super.clone(); // 浅拷贝Person对象
    person.address = (Address) address.clone(); // 深拷贝Address对象
    return person;
}

这样,原始Person对象和副本将引用不同的Address对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值