面试官:深拷贝与浅拷贝有啥区别?

这篇具有很好参考价值的文章主要介绍了面试官:深拷贝与浅拷贝有啥区别?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.前言

首先,明确一点深拷贝和浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这个时候你修改两者中的任何一个的值都不会影响另一个,而对象或者引用数据来说在进行浅拷贝时,只是将对象的引用复制了一份,也就内存地址;即两个不同的变量指向了同一个内存地址,那么在改变任一个变量的值都是改变这个内存地址所指向的值,所以两个变量的值都会改变。
上方这句话不太好理解,这样,我把他们区别出来,做两个讲解,一个是关于基本类型的拷贝;一个关于引用数据类型的拷贝,分开理解,会大大降低学习成本~

2.基本类型的拷贝

在基本类型的拷贝中,深拷贝浅拷贝的作用就没什么区别了,拷贝出来的对象都是拥有相同的数值,这里用语言文字很难描述,可以看下面的代码和图来帮助理解。

    public static void main(String[] args) throws CloneNotSupportedException {
        //原来的对象
        Person person1=new Person("张三",15);
        //克隆出来的对象
        Person person2=(Person) person1.clone();
    }

我们打印这两个对象的地址:
观察可以看出,他两个的地址是不相同的,也就是说,他两个现在是不同的对象。
面试官:深拷贝与浅拷贝有啥区别?
他两个在堆、栈图中是如何表示的呢?看下方的图:
我们可以看出,p2p1中的所有数据都重新生成了一份,让给让p2指向新生成的那份数据。
面试官:深拷贝与浅拷贝有啥区别?

3.引用类型的拷贝

这个就很有引用类型拷贝就会在深拷贝浅拷贝上区别很大了!
我们仍然以人来举例子,人身上一般都会带着money,我们给人添加一个新的成员变量(钱),并且我们让钱这个成员变量改为引用变量

3.1 关于引用类型的浅拷贝


class Money {
    public double value=99.99;


}

class Person implements Cloneable{
    public String name;
    public int age;
    public Money money=new Money();

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

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

    public static void main(String[] args) throws CloneNotSupportedException {
        //原来的对象
        Person person1=new Person("张三",15);
        //克隆出来的对象
        Person person2=(Person) person1.clone();
        System.out.print("p1的钱钱数:");
        System.out.println(person1.money.value);
        
        System.out.print("p2的钱钱数:");
        System.out.println(person2.money.value);
    }
}

打印出来的结果:

p1的钱钱数:99.99
p2的钱钱数:99.99

我们可以观察结果得出,p1的钱钱和p2的钱钱我们设置好的99.99。
当我们去尝试修改p1钱钱的数时:

public static void main(String[] args) throws CloneNotSupportedException {
        //原来的对象
        Person person1=new Person("张三",15);
        //克隆出来的对象
        Person person2=(Person) person1.clone();

        System.out.println("修改p1的钱钱数");
        person1.money.value=50;

        System.out.print("p1的钱钱数:");
        System.out.println(person1.money.value);

        System.out.print("p2的钱钱数:");
        System.out.println(person2.money.value);
    }

代码打印结果:
面试官:深拷贝与浅拷贝有啥区别?
我去,你修改p1的钱钱数,为啥我p2的钱钱数也发送了改变,这不就相当于别人花的钱扣在了我身上?这可不是我想要的结果!
这到底怎能回事?其实很好理解,当我们在进行拷贝时,我们拷贝money这个成员变量时,我们拷贝的数值是一个引用变量,这个引用变量又指向一个对象。因此当我们修改p1的钱的数值时,我们时顺着引用变量找所指向的值将其修改了,又因为两个引用对象指向同一个值,因此修改后,再通过引用变量查看值,就是修改后的值了;上述过程就是浅拷贝了,它的结构图如下:
面试官:深拷贝与浅拷贝有啥区别?

3.2 关于引用类型的深拷贝

如何解决这样的问题呢?其实很简单,当我们进行拷贝时,我们让引用变量引用的对象重新创建一个新的对象,并且让拷贝的那一份的引用变量指向创建的对象。
我们主要修改的就算Person类中的clone方法,我们先让Money类实现Cloneable接口,然后在Person类中的clone方法调用Money类中的clone方法。(这里比较绕,看不懂没关系,下面有画的结构图,图看起来会很好理解!)


class Money implements Cloneable{
    public double value=99.99;

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

class Person implements Cloneable{
    public String name;
    public int age;
    public Money money=new Money();

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person person=(Person) super.clone();
        person.money=(Money) person.money.clone();
        return person;
    }
}
public class testDemo2 {

    public static void main(String[] args) throws CloneNotSupportedException {
        //原来的对象
        Person person1=new Person("张三",15);
        //克隆出来的对象
        Person person2=(Person) person1.clone();

        System.out.println("修改p1的钱钱数");
        person1.money.value=50;

        System.out.print("p1的钱钱数:");
        System.out.println(person1.money.value);

        System.out.print("p2的钱钱数:");
        System.out.println(person2.money.value);
    }
}

代码运行出来的结果:
可以看出,修改p1的钱数,不在应用p2的钱数了。
面试官:深拷贝与浅拷贝有啥区别?
上方这个过程就是深拷贝,深拷贝的结构图如下:
面试官:深拷贝与浅拷贝有啥区别?文章来源地址https://www.toymoban.com/news/detail-468626.html

到了这里,关于面试官:深拷贝与浅拷贝有啥区别?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中的深拷贝与浅拷贝

    深拷贝和浅拷贝是编程中常用的两种对象复制方式,它们在复制对象时处理对象内部引用的方式上有所不同。 浅拷贝 浅拷贝(Shallow Copy)只复制对象的顶层结构,而不复制对象内部的引用对象。换句话说,浅拷贝只复制对象的值类型字段和引用类型字段的引用,而不复制引

    2024年01月22日
    浏览(27)
  • 简单理解Python中的深拷贝与浅拷贝

    I. 简介 深拷贝会递归的创建一个完全独立的对象副本, 包括所有嵌套的对象 ,而浅拷贝只 复制嵌套对象的引用 ,不复制嵌套对象本身。 简单来说就是两者都对原对象进行了复制,因此使用is运算符来比较新旧对象时,返回的都是False(都开辟了新的内存);两者区别在于 对嵌

    2024年02月12日
    浏览(31)
  • 【Python】python深拷贝与浅拷贝详解(必须掌握)

    深拷贝和浅拷贝是python必须要掌握的内容,无论你是面试开发、测试、运维等职位,只要是python,深拷贝与浅拷贝是面试官常问的一个重要知识点。 (关注“测试开发自动化” 弓中皓,获取更多学习内容) 相同点: 无论深拷贝还是浅拷贝都会创建一个新对象。即:拷贝出来

    2024年03月25日
    浏览(29)
  • Java中的集合及深拷贝与浅拷贝

    Java是一种面向对象的编程语言,其中集合是常用的数据结构之一,具有方便快捷的特点。在Java开发中,我们常常需要对集合进行复制(拷贝)操作。但是,拷贝操作并不是简单的复制,而应该分为浅拷贝和深拷贝两种不同的方式,本文将分别介绍Java中集合的浅拷贝和深拷贝

    2024年02月07日
    浏览(25)
  • Java面试必备:深拷贝、浅拷贝、引用拷贝的区别

    Java中的拷贝可以分为深拷贝(Deep Copy)、浅拷贝(Shallow Copy)和引用拷贝(Reference Copy)。它们之间的区别如下: 浅拷贝: 只复制对象本身,而不复制对象包含的子对象。新旧对象之间共享子对象的引用,即新对象和原始对象中的子对象指向同一个内存地址。 浅拷贝:使用

    2023年04月11日
    浏览(24)
  • 深入探索前端之道:JavaScript深拷贝与浅拷贝的解析与实现

    前端开发中,数据的复制是一个常见的操作。尤其是在处理对象和数组时,我们需要考虑的是一个浅拷贝还是深拷贝。那么,什么是深拷贝和浅拷贝?它们在前端开发中有什么作用?如何实现这两种拷贝?这是我们在本文将讨论的问题。 浅拷贝 浅拷贝是一种数据复制方式,

    2024年02月10日
    浏览(27)
  • 服务器和电脑有啥区别?

    服务器可以说是“高配的电脑”,两者都有CPU、硬盘、电源等基础硬件组成,但服务器和电脑也是有一定区别的,让小编带大家了解一下吧! #秋天生活图鉴# 1、稳定性需求不同:服务器是全年无休,需要高稳定性,很多时候服务器就只有一次开机机会,接着就要提供高强度

    2024年02月01日
    浏览(34)
  • TCP 和UDP 到底有啥区别

    TCP(传输控制协议)和UDP(用户数据报协议)是互联网上常用的两种传输层协议,它们在数据传输方式和特性上有显著的区别。下面是TCP和UDP的主要区别: 连接性 : TCP 是一种面向连接的协议。在数据传输前,它需要在发送方和接收方之间建立一个连接。这个过程通常涉及一

    2024年02月03日
    浏览(27)
  • CISAW认证,与CISP认证有啥区别?

    CISAW(信息安全保障人员认证)是CCRC(中国网络安全审查技术与认证中心)推出的一个证书。 CISP是国家信息安全测评中心推出的一个证书。 这两个机构都可以颁发信息安全服务相关资质,它俩没有直接关系。 两个机构都推出了信息安全相关的证书,一个是CISAW,一个是CIS

    2024年02月10日
    浏览(29)
  • 深入与浅谈 Vue 中计算属性和侦听器的区别和使用(Vue3版本为例)

    #五一技术创作马拉松# 计算属性 computed 和侦听器 watch 都是 Vue.js 框架中用来响应式更新视图的重要概念。在 Vue 项目开发中,这两个技术点是非常重要的,同时也是 Vue 基础中不可缺少的知识点。在面试中,计算属性 computed 和侦听器 watch 也是经常出现的考点,作为前端开发也

    2024年02月07日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包