深拷贝和浅拷贝

深拷贝和浅拷贝就是指对象的拷贝,一个对象中存在两种类型的属性,一种是基本数据类型,一种是实例对象的引用。

1.浅拷贝是指,对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝。

2.深拷贝是指,对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容,此为深拷贝。

浅拷贝例子:

package se.copy;

import lombok.Data;

class Person implements Cloneable {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Phone getPhone() {
        return phone;
    }
    public void setPhone(Phone phone) {
        this.phone = phone;
    }
    private Phone phone;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

class Phone implements Cloneable {
    private String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class ShallowCopy {
    // 浅拷贝
    public static void main(String[] args) throws CloneNotSupportedException {
        Phone phone = new Phone();
        phone.setName("小米");

        // 创建一个Person对象(原对象)
        Person person = new Person();
        person.setName("hzk");
        // 设置引用类型属性
        person.setPhone(phone);
        // 打印原对象的属性值
        System.out.println(person);
        System.out.println(person.getName());
        System.out.println(person.getPhone());
        System.out.println(person.getPhone().getName());

        System.out.println("-----------------");
        // 克隆一个Person对象(克隆对象)
        Person copyPerson = (Person) person.clone();
        // 打印克隆对象的属性值
        System.out.println(copyPerson);
        System.out.println(copyPerson.getName());
        System.out.println(copyPerson.getPhone());
        System.out.println(copyPerson.getPhone().getName());

        // 浅拷贝由于会拷贝引用数据类型的地址,因此修改拷贝对象的值,其被拷贝对象的值也会跟着变化。反之,同理。
        copyPerson.getPhone().setName("华为");

        System.out.println("原对象的引用类型Phone值" + person.getPhone().getName());
        System.out.println("克隆对象的引用类型Phone值" + copyPerson.getPhone().getName());

    }

}

运行结果:

深拷贝例子:

package se.copy;

class Person1 implements Cloneable {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Phone1 getPhone() {
        return phone;
    }

    public void setPhone(Phone1 phone) {
        this.phone = phone;
    }

    private Phone1 phone;

    @Override
    protected Object clone() throws CloneNotSupportedException {
//        return super.clone();
        //继续利用clone()方法,对该对象的引用类型变量再实现一次clone()方法。
        // 要想深克隆 要不就是序列化和反序列化 要不就是继续clone
        Person1 person = (Person1) super.clone();
        person.setPhone((Phone1) person.getPhone().clone());
        return person;
    }
}

class Phone1 implements Cloneable {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class DeepCopy {

    // 深拷贝
    public static void main(String[] args) throws CloneNotSupportedException {
        Phone1 phone1 = new Phone1();
        phone1.setName("小米");

        Person1 person1 = new Person1();
        person1.setName("hzk");
        person1.setPhone(phone1);

        System.out.println(person1);
        System.out.println(person1.getName());
        System.out.println(person1.getPhone());
        System.out.println(person1.getPhone().getName());

        System.out.println("-----------------");
        Person1 copyPerson1 = (Person1) person1.clone();
        System.out.println(copyPerson1);
        System.out.println(copyPerson1.getName());
        System.out.println(copyPerson1.getPhone());
        System.out.println(copyPerson1.getPhone().getName());

        System.out.println("-----------------");
        // 深拷贝不会拷贝引用数据类型的地址(而是会创建一个新对象空间),因此修改拷贝对象的值,其被拷贝对象的值不会跟着变化。反之,同理。
        copyPerson1.getPhone().setName("华为");

        System.out.println("原对象的引用类型Phone值---" + person1.getPhone().getName());
        System.out.println("克隆对象的引用类型Phone值---" + copyPerson1.getPhone().getName());
    }
}

运行结果

理解:深拷贝和浅拷贝的作用和场景

深拷贝和浅拷贝在编程中都有重要的应用场景。

        深拷贝主要用于需要修改原对象但又不希望影响原对象的场景。例如,当您需要使用一个对象作为参数传递给函数,同时又不想因为这个函数内部对对象的修改而改变原对象时,就需要使用深拷贝来创建一个新的独立的对象副本。此外,当您从数据库中读取一些数据并想在此基础上做一些改动,但又希望保持原数据的完整性时,深拷贝也是一个理想的选择。

        相反,浅拷贝通常用于原始对象和拷贝对象需要共享相同数据的场景。例如,如果您有一个包含大量数据的对象,并且您只想复制该对象的一部分数据到另一个新的对象中,那么浅拷贝就非常适用,因为它只复制了对象的引用,而不是对象本身。此外,如果对象非常大,并且只需要偶尔进行修改,那么浅拷贝由于其较低的内存消耗可能会是更好的选择。

        总的来说,深拷贝和浅拷贝的选择取决于具体的应用场景和需求,理解它们的区别对于正确处理对象和数组的复制至关重要。

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值