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

news/2025/2/21 12:57:54/

文章目录

  • 1.前言
  • 2.基本类型的拷贝
  • 3.引用类型的拷贝
    • 3.1 关于引用类型的浅拷贝
    • 3.2 关于引用类型的深拷贝

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;}@Overrideprotected 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;@Overrideprotected 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;}@Overrideprotected 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的钱数了。
在这里插入图片描述
上方这个过程就是深拷贝,深拷贝的结构图如下:
在这里插入图片描述


http://www.ppmy.cn/news/167050.html

相关文章

macbook pro window蓝牙驱动 下载

macbook pro的蓝牙驱动一直找不到,使用DRIVERTOOLKIT 更新成功,将蓝牙驱动备份下来。放在百度网盘下,供使用 链接: https://pan.baidu.com/s/1vfuvyFdegB3kn2PPiqsn9w 提取码: jktz 接小米鼠标会有断的现象,这个驱动,…

惠普电脑使用蓝牙连接蓝牙设备

电脑原装的驱动是windows自带的旧驱动,需到惠普官网下载新的驱动 下载地址:https://support.hp.com/cn-zh/drivers/laptops 安装驱动 在设备管理中卸载蓝牙设备,重新添加蓝牙设备 这样操作之后在右侧托盘中会有蓝牙标记 右键点击蓝牙标记–&…

笔记本蓝牙突然消失

蓝牙突然消失有可能是 因为电脑产生静电,关机后,切开电源长按开机键20秒释放静电。 之后打开设备管理器,看是否会出现有未知设备描述符请求失败 打开隐藏设备 看蓝牙选项中,蓝牙是灰色的就是不可用, 把未知设备卸掉或…

Windows10蓝牙驱动丢失,100%解决方案

1.打开控制面板 2.设备和打印机 3.找到如下设备(应该会有个!警告) 4.右键->疑难解答 5.一步步修复,最后关机重启即可。

华为matebook重装win11系统后,蓝牙失效无法使用,重新安装蓝牙驱动

华为电脑重新安装win11系统后,蓝牙无法使用,华为电脑管家无法更新驱动 浏览器搜索 华为电脑驱动 进入华为官方驱动程序下载网站,下载对应产品型号的蓝牙驱动,安装即可。

使用过程中蓝牙驱动突然消失

在和我的蓝牙键盘快乐共舞的时候,突然间,键盘就不能使用了,仔细一看,是蓝牙这个功能就消失了,记录一下 1 试错心得,不要下载一键驱动安装管家 没用 2 在联想驱动官网下载找到设备驱动之后,不要…

笔记本蓝牙搜索不到设备解决方案

1、蓝牙驱动已经安装 2、蓝牙相关配置已打开 上面都已经配置好了 为啥还是不能连接蓝牙设备呢? 那么问题就在这: 首先,我们使用快捷键WindowX打开超级菜单,点击设备管理器; 找到蓝牙 我们右键对这两个进行更新 更新…

台式计算机能不能安装蓝牙驱动,台式电脑蓝牙驱动安装失败怎么办?台式电脑蓝牙驱动安装失败解决办法...

提到蓝牙驱动,大多数人想到手机和笔记本电脑等移动设备,但是台式电脑也是可以安装蓝牙驱动的,只不过很多用户常常会遇到蓝牙驱动安装失败的情况,究其原因大多是优化软件将系统INF文件夹自带文件误删了。那么这种情况应该如何解决呢…