深拷贝和浅拷贝的区别

1、定义

深拷贝:

在Java中,深拷贝(Deep Copy)是指创建一个新对象,并将原始对象中的所有字段及其引用的对象都复制一份到新对象中,即使这些引用的对象也会被复制,而不是简单地复制引用。这意味着原始对象及其所有嵌套对象的状态在内存中存在两个独立的拷贝,彼此之间互不影响。
如果你没有看懂,换一个说法:用生活中例子来解释。
假设你有一本笔记本,里面记录着你去过的城市和你在每个城市的见闻。这个笔记本就代表了一个对象。现在,你要把这个笔记本的内容复制一份,但是不仅仅是复制内容,而是要把每个城市的见闻都重新写一遍到一个新的笔记本上,这样新的笔记本就和原来的完全独立,互不影响。这就是深拷贝的概念。

深拷贝图例:

在这里插入图片描述

浅拷贝:

在Java中,浅拷贝(Shallow Copy)是指创建一个新对象,然后将原始对象中的所有字段复制到新对象中,但对于引用类型的字段,只复制引用而不复制引用指向的对象。这意味着新对象与原始对象共享同一组引用对象,而不是拥有它们的副本。
如果你没有看懂,换一个说法:用生活中例子来解释。
假设你有一个购物清单A,其中包含了物品名称和数量,例如:{“苹果”: 3, “香蕉”: 2, “橙子”: 5}。
你想要创建一个新的购物清单B,其中包含了与清单A相同的物品和数量。
通过浅拷贝,你创建了一个新的购物清单B,并将清单A中的物品名称和数量复制到了清单B中。这样,清单A和清单B中的物品名称和数量都是相同的,但它们引用的是相同的物品对象。如果你在清单A中修改了物品的数量,那么清单B中对应的物品数量也会被修改,因为它们共享同一个物品对象。

浅拷贝的图例

在这里插入图片描述

区别:

这里我就举例子了。
假设你有一个家庭成员名单,上面列出了你的家庭成员及其联系方式。这个名单就代表了一个对象。
现在,你要复制这个名单给你的朋友,让他也能知道你的家庭成员。这就是拷贝的行为。
浅拷贝:你把名单复制了一份给你的朋友,但是在复制的时候,你只复制了名单上的内容,而没有复制每个家庭成员的联系方式。所以,你的朋友得到了一个新的名单,但是名单上的每个家庭成员的联系方式都指向同一个家庭成员的联系方式。如果你的朋友修改了名单上某个家庭成员的联系方式,那么这个修改也会反映在你手里的名单上,因为它们共享同一个联系方式。这就是浅拷贝的特点:共享嵌套对象。
深拷贝:你把名单复制了一份给你的朋友,但是这次你不仅复制了名单上的内容,还逐一复制了每个家庭成员的联系方式。这样,你的朋友得到了一个全新的名单,上面的每个家庭成员的联系方式都是独立的,修改其中一个家庭成员的联系方式不会影响到原来的名单。这就是深拷贝的特点:每个嵌套对象都是独立的,互不影响。

上代码:

浅拷贝:

import java.util.ArrayList;
import java.util.List;

class Student implements Cloneable {
    private String name;
    private List<String> subjects;

    public Student(String name, List<String> subjects) {
        this.name = name;
        this.subjects = subjects;
    }

    // 实现浅拷贝
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public String getName() {
        return name;
    }

    public List<String> getSubjects() {
        return subjects;
    }
}

public class ShallowCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        List<String> subjects = new ArrayList<>();
        subjects.add("java语言程序设计");
        subjects.add("C++从入门到精通");
        Student original = new Student("张三", subjects);
        Student cloned = (Student) original.clone();

        System.out.println("原对象: " + original.getName() + ", 科目: " + original.getSubjects());
        System.out.println("克隆对象: " + cloned.getName() + ", 科目: " + cloned.getSubjects());
        // 修改原对象的科目列表
        original.getSubjects().add("php从入门到精通");

        System.out.println("修改后的原对象: " + original.getName() + ", 科目: " + original.getSubjects());
        System.out.println("修改后的克隆对象: " + cloned.getName() + ", 科目: " + cloned.getSubjects());
    }
}

输出结果:
在这里插入图片描述
深拷贝:

import java.util.ArrayList;
import java.util.List;

class Student implements Cloneable {
    private String name;
    private List<String> subjects;

    public Student(String name, List<String> subjects) {
        this.name = name;
        this.subjects = subjects;
    }

    // 实现深拷贝
    @Override
    public Object clone() throws CloneNotSupportedException {
        Student cloned = (Student) super.clone();
        // 对于引用类型字段,进行额外的拷贝
        cloned.subjects = new ArrayList<>(this.subjects);
        return cloned;
    }

    public String getName() {
        return name;
    }

    public List<String> getSubjects() {
        return subjects;
    }
}

public class DeepCopyExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        List<String> subjects = new ArrayList<>();
        subjects.add("java语言程序设计");
        subjects.add("C++从入门到精通");
        Student original = new Student("张三", subjects);
        Student cloned = (Student) original.clone();
        System.out.println("原对象: " + original.getName() + ", 科目: " + original.getSubjects());
        System.out.println("克隆对象: " + cloned.getName() + ", 科目: " + cloned.getSubjects());
        // 修改原对象的科目列表
        original.getSubjects().add("php从入门到精通");
        System.out.println("修改后的原对象: " + original.getName() + ", 科目: " + original.getSubjects());
        System.out.println("修改后的克隆对象: " + cloned.getName() + ", 科目: " + cloned.getSubjects());
    }
}

运行结果:
在这里插入图片描述

  • 16
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱写Bug的小孙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值