浅拷贝和深拷贝的区别?

python之浅拷贝和深拷贝的区别 赋值 在我们开始讨论浅拷贝和深拷贝的区别之前,首先我们必须清楚什么是赋值? 在Python中,所谓的赋值实际上就是对象引用的传递而已,当创建一个对象的时候,再赋值给另外一个变量的时候,并不是赋值给另一个变量。而是把这个变量在地址空间的id地址值传递给另一个变量,简单的说就是拷贝了这个对象的引用。看图片,可能比较容易理解。 从图中,我们很容易的看到,a和b两个变量在地址空间中是一样。后来,我们又给... 阅读详情

创建Java对象的方式包括new、反射、反序列化、拷贝,那么什么是拷贝呢?浅拷贝和深拷贝又有什么区别呢?

什么是拷贝

拷贝就是为了复用原对象的部分或全部数据,在原对象的基础上通过复制的方式创建一个新的对象。

Object类中有native类型的clone方法

protected native Object clone() throws CloneNotSupportedException;

如果一个对象可以被拷贝,那么该对象对应的类需要实现Cloneable接口,并重写Object的clone方法。

必须实现Cloneable接口,否则调用clone方法会抛出java.lang.CloneNotSupportedExecption异常

//Cloneable接口中没有任何参数或抽象方法,该接口只是一个标识
public interface Cloneable {
}

//如Student类,实现Cloneable接口,重写Object的clone方法
public class Student implements Cloneable{

    private String sname;

    private Integer sage;

    ...

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

举个栗子

public class cloneObject {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student student = new Student("学生1",18);
        System.out.println("clone前的Student对象为:"+student);
        Student cloneStudent = student.clone();
        System.out.println("clone后的Student对象为:"+cloneStudent);
        System.out.println("Student对象与cloneStudent对象是否相等:"+student.equals(cloneStudent));
    }
}

打印结果为

clone前的Student对象为:Student{sname='学生1', sage=18}
clone后的Student对象为:Student{sname='学生1', sage=18}
Student对象与cloneStudent对象是否相等:false

由此可见,拷贝是创建了一个新的对象。

什么是浅拷贝?

我稍等改动下Student类来举例说明

Student类中除了String类型和Integer类型的属性外,添加了一个Teacher类型的属性,Teacher类中只有一个String类型的tname属性

public class Student implements Cloneable{

    private String sname;

    private Integer sage;

    private Teacher teacher;

    ...

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

public class Teacher {

    private String tname;

再次调用sutdent对象的clone方法

public static void main(String[] args) throws CloneNotSupportedException {
    Teacher teacher = new Teacher("罗翔老师");
    Student student = new Student("学生1",18,teacher);
    System.out.println("clone前的Student对象为:"+student);
    Student cloneStudent = student.clone();
    System.out.println("clone后的Student对象为:"+cloneStudent);
    System.out.println("Student对象与cloneStudent对象是否相等:"+student.equals(cloneStudent));
    System.out.println("student对象和cloneStudent对象中的teacher属性是否相等:"+student.getTeacher().equals(cloneStudent.getTeacher()));
}

两个sutdent对象比较结果在意料之中,为false。但是两种student对象中的teacher属性比较结果却是true。

clone前的Student对象为:Student{sname='学生1', sage=18, teacher=com.hard.qz.clone.Teacher@1b6d3586}
clone后的Student对象为:Student{sname='学生1', sage=18, teacher=com.hard.qz.clone.Teacher@1b6d3586}
Student对象与cloneStudent对象是否相等:false
student对象和cloneStudent对象中的teacher属性是否相等:true

//修改student对象中teacher属性的值,观察cloneStudent对象中的teacher属性的值是否会变
student.getTeacher().setTname("张三老师");
System.out.println("cloneStudent对象中teacher属性的值为:"+cloneStudent.getTeacher());

结果为:

cloneStudent对象中teacher属性的值为:Teacher{tname='张三老师'}

当修改student对象中teacher属性的值时,会影响到cloneStudent对象中teacher属性的值 由此说明:两个student对象共用一个teacher对象。

像上面这种情况,当拷贝时,只拷贝了部分属性,没有拷贝Object和数组属性时,这种拷贝被称为浅拷贝。

什么是深拷贝?

当拷贝时,拷贝了一个对象中的所有属性,包括Object和数组属性,这种拷贝被称为深拷贝

如何实现深拷贝?

重写clone方法时,对Object和数组属性也调用clone方法就可以实现深拷贝,要求被拷贝对象的Object属性也实现Cloneable接口,重写了clone方法。

//Teacher类实现了Cloneable接口,重写了clone方法
public class Teacher implements Cloneable{

    private String tname;

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

//Student类重写clone方法时,调用了Teacher类的clone方法,实现深拷贝
@Override
protected Student clone() throws CloneNotSupportedException {
    Student cloneStudent = (Student) super.clone();
    cloneStudent.setTeacher((Teacher) cloneStudent.getTeacher().clone());
    return cloneStudent;
}

对student对象拷贝并比较两个对象及对象中的属性是否相等。

public class cloneObject {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher("罗翔老师");
        Student student = new Student("学生1",18,teacher);
        System.out.println("clone前的Student对象为:"+student);
        Student cloneStudent = student.clone();
        System.out.println("clone后的Student对象为:"+cloneStudent);
        System.out.println("Student对象与cloneStudent对象是否相等:"+student.equals(cloneStudent));
        System.out.println("student对象和cloneStudent对象中的teacher属性是否相等:"+student.getTeacher().equals(cloneStudent.getTeacher()));

        //修改student对象中teacher属性的值,观察cloneStudent对象中的teacher属性的值是否会变
        student.getTeacher().setTname("张三老师");
        System.out.println("cloneStudent对象中teacher属性的值为:"+cloneStudent.getTeacher());
    }
}

打印结果为

clone前的Student对象为:Student{sname='学生1', sage=18, teacher=Teacher{tname='罗翔老师'}}
clone后的Student对象为:Student{sname='学生1', sage=18, teacher=Teacher{tname='罗翔老师'}}
Student对象与cloneStudent对象是否相等:false
student对象和cloneStudent对象中的teacher属性是否相等:false
cloneStudent对象中teacher属性的值为:Teacher{tname='罗翔老师'}

打印结果显示深拷贝后的两个对象及其中的属性都不相等。

总结

  1. 拷贝是为了部分或全部复用原对象的属性,在元对象的基础上创建一个新的对象。
  2. 浅拷贝是拷贝后两个对象地址不相等,但两个对象的部分属性地址相等,新对象并没有拷贝所有的属性,而是复用原对象中的值。
  3. 深拷贝是拷贝后两个对象不仅地址不相等,两个对象的所有属性地址都不相等。
【JS专栏】JS对象的浅拷贝与深拷贝 浅拷贝 自己创建一个新的对象,来接受你要重新复制或引用的对象值。如果对象属性是基本的数据类型,复制的就是基本类型的值给新对象;但如果属性是引用数据类型,复制的就是内存中的地址,如果其中一个对象改变了这个内存中的地址,肯定会影响到另一个对象。 ​ 1. object.assign object.assign 是 ES6 中 object 的一个方法,该方法可以用于JS 对象的合并等多个用途,其中一个用途就是可以进行浅拷贝。 该方法的第一个参数是拷贝的目标对象,后面的参数是拷贝的来源对象(也可以是多个来源)。 阅读详情

相关推荐

12.散列表设计思想和原理

目录介绍 01.对象拷贝有哪些 02.理解浅拷贝 2.1 什么是浅拷贝 2.2 实现浅拷贝案例 03.理解深拷贝 3.1 什么是深拷贝 3.2 实现深拷贝案例 04.序列化进行拷贝 4.1 序列化属于深拷贝 4.2 注意要点 4.3 序列化案例 05.延迟拷贝 06.如何选择拷贝方式 07.数组的拷贝 7.1 基本数据类型数组 7.2 引用数据类型数组 08.集合的拷贝 ...

杨充 432

理解深拷贝和浅拷贝

目录 一、深浅拷贝是什么? 二、深浅拷贝基础(数据类型) 1.基础数据类型(值传递) 2.复杂数据类型(地址传递) 三、深浅拷贝怎样操作(代码示例) 1.浅拷贝: 1)通过Object.assign for in 进行浅拷贝 2.深拷贝: 1)深拷贝最简单的实现是: JSON.parse(JSON.stringify(obj)) 2)实现一个 deepClone 函数 (深拷贝,完美) 3)递归拷贝 一、深浅拷贝是什么? 首先我们要明白一点,js中数据类...

m0_65558076的博客 3万+

ck3m多轴运动控制器笔记1:电机的配置与注意事项

利用PMAC(CK3M)运动控制器来实现对电机的控制,对具体的配置流程和注意事项讲解

p975468132的博客 4641

深拷贝|浅拷贝

深拷贝-浅拷贝

伏颜的博客 8185

YOLOv11 改进 - 注意力机制 | 空间增强注意力SEAM(Spatially Enhanced Attention Module)提升遮挡场景检测鲁棒性

本文介绍了分离与增强注意力模块(SEAM)在YOLOv11中的结合应用。SEAM模块旨在增强面部特征学习能力,特别是处理面部遮挡问题。它采用多头注意力机制强调面部区域、抑制背景区域,第一部分使用深度可分离卷积减少参数并学习通道重要性,通过1x1卷积增强通道联系,利用两层全连接网络融合通道信息,经指数归一化后作为注意力权重与原始特征相乘。我们将SEAM集成到YOLOv11的检测头中,并进行相关注册和配置。实验表明,该方法有助于提升模型检测性能。

魔改工程师的博客 1665

Slow waitForAckedSeqno took 64873ms (threshold=30000ms). File being written

Slow waitForAckedSeqno took 64873ms (threshold=30000ms). File being written

zhengzaifeidelushang的博客 2011

浅拷贝、深拷贝

深拷贝和浅拷贝   这两个概念是在项目中比较常见的,在很多时候,都会遇到拷贝的问题,我们总是需要将一个对象赋值到另一个对象上,但可能会在改变新赋值对象的时候,忽略掉我是否之后还需要用到原来的对象,那么就会出现当改变新赋值对象的某一个属性时,也同时改变了原对象,此时我们就需要用到拷贝这个概念了。 深拷贝和浅拷贝的区别 1.浅拷贝: 将原对象或原数组的引用直接赋...

Addisoni 4万+

AHB—SRAMC项目(结构图,核心代码、Testbench架构)

文章目录一、AHB_SRAMC项目介绍1.1.AHB总线控制单元(ahb_slv_if.v)1.2.SRAM控制单元(sramc_top.v)1.3.主要的传输路径二、结构框图2.1.AHB_SRAMC结构图(重点)2.2.总线控制单元与SRAM控制单元结构图三、部分核心代码(重点理解)四、SystemVerilog Testbench架构(重点)五、目录结构 一、AHB_SRAMC项目介绍 本项...

Mr.翟的博客 3万+

深拷贝与浅拷贝的原理和区别

我特别想写这篇,因为我看到了一篇非常非常优秀的博客,讲的巨好!直接贴上链接,强烈建议大家去阅读原博主的 https://www.cnblogs.com/echolun/p/7889848.html 1.深拷贝和浅拷贝的区别 B复制A,A变,B变,浅拷贝。 B复制A,A变,B不变,深拷贝。 举个简单example 平常的a赋值给b,a变,b并不会变。而对于对象obj2,这种简单的赋值,obj变,obj2变,就是浅拷贝了。 这是为啥呢?这就要我们从数据类型说起了。。。。 2.基本数据类型和引用数据类型 基

weixin_43795084的博客 1万+

【python】懂车帝字体反爬逐层解密案例(附完整代码)

懂车帝字体反爬解密,完整代码分享

景天科技苑 2万+

TC3XX - MCAL知识点(二十四):UART MCAL配置及代码实战

UART驱动程序负责按照UART协议提供通信服务。ASCLIN模块为异步通信提供硬件支持,实现UART协议。UART驱动程序提供了配置、初始化、数据传输、接收等功能,还提供了中止传输和中止接收 abort等可选特性。软硬件匹配关系如下:UART驱动程序使用ASCLIN进行数据的传输和接收。驱动程序使用的关键硬件功能特性是:1、全双工异步工作模式2、支持半双工工作模式3、16字节的TXFIFO4、16字节的RXFIFO5、2 ~ 16位数据帧6、校验位生成/检查7、一个或两个停止位。

梦想技术家 1832

浅拷贝与深拷贝的区别(详解)

浅拷贝与深拷贝的区别 html 浅拷贝与深拷贝 一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。 基本数据类型的特点:直接存储在栈(stack)中的数据 引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。 ​​ 二、浅拷贝与深拷贝 深拷贝和浅拷

Mark Sheng的博客 12万+

PCB仿真软件:Altium Designer_(18).PCB设计中的热管理

在PCB设计中,热管理是一个至关重要的环节。随着电子设备的集成度越来越高,功耗和发热量也随之增加,不合理的热设计可能导致电路板过热,从而影响电路的性能和可靠性。热管理不仅能够提高电路板的使用寿命,还能确保电路在各种环境条件下的稳定工作。本节将详细介绍如何在Altium Designer中进行有效的热管理,包括热分析、热设计和热仿真等关键步骤。

kkchenjj的博客 1986

浅拷贝与深拷贝的区别

浅拷贝与深拷贝 一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined,Symbol)和对象数据类型。 基本数据类型的特点:直接存储在栈(stack)中的数据 引用数据类型的特点:存储的是该对象在栈中引用,真实的数据存放在堆内存里 引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。 二、浅拷贝与深拷贝 深拷贝和浅拷贝是只针对Object和Array这样的引用数

SSophia的博客 7万+

超越防抖:索尼CXD5254GG芯片如何重新定义电子影像稳定

索尼CXD5254GG芯片通过融合6轴IMU与图像传感器数据,重新定义了电子影像稳定技术。其核心突破在于实时地平线校正、抑制果冻效应和镜头畸变校正,并搭载智能画质控制器提升画面细节。该芯片适用于广播制作、体育娱乐、安防监控和机器人视觉导航等专业领域,提供开箱即用的优化参数配置,大幅缩短开发周期。CXD5254GG不仅实现稳定成像,更通过姿态感知与智能优化,为专业影像应用提供了完整的稳定解决方案。

致力于lidar应用开发 114

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

一文彻底搞懂深拷贝和浅拷贝的区别

深拷贝(Deep Copy)和浅拷贝(Shallow Copy)是在复制对象或数据结构时所使用的两种不同的拷贝方法,它们之间的区别主要在于拷贝的程度和对原始对象内部结构的影响。

永远在路上 1万+

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Python 深拷贝和浅拷贝的区别

Python 深拷贝和浅拷贝的区别 深浅拷贝在python中经常使用,其区别的外在表现是: 使用浅拷贝,当原容器对象中可变对象中有元素发生变化,拷贝得到的对象也会变化。而使用深拷贝时,不会有这种问题。 浅拷贝: # -*- coding: utf-8 -*- # @File : 浅拷贝.py # @Author : Runpeng Zhang # @Date : 2020/2/10 # @...

Rp的博客 4654

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

python的复制,深拷贝和浅拷贝的区别

python的复制,深拷贝和浅拷贝的区别 在python中,对象赋值实际上是对象的引用。当创建一个对象,然后把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用 一般有三种方法, alist=[1,2,3,["a","b"]] (1)直接赋值,默认浅拷贝传递对象的引用而已,原始列表改变,被赋值的b也会做相同的改变 >>> b=ali...

zhubaoJay的博客 2万+

C++浅拷贝和深拷贝的区别

先考虑一种情况,对一个已知对象进行拷贝,编译系统会自动调用一种构造函数——拷贝构造函数,如果用户未定义拷贝构造函数,则会调用默认拷贝构造函数。 先看一个例子,有一个学生类,数据成员时学生的人数和名字: #include <iostream> using nam...

测试0901-1 9517

深拷贝和浅拷贝的区别

目录 深拷贝和浅拷贝 值类型 vs 引用类型 赋值 vs 浅拷贝 vs 深拷贝 对象赋值 浅拷贝 深拷贝 浅拷贝代码实现 深拷贝代码实现 深度遍历式拷贝 利用反序列化实现深拷贝 深拷贝和浅拷贝 浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址, 深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存, 使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。 浅复制:仅仅是指向被复制的.

一蓑烟雨任平生 4753

【C#】深拷贝和浅拷贝、区别

浅拷贝:只复制值类型字段,引用类型字段只复制引用,使用实现。深拷贝:递归复制所有引用类型字段,创建完全独立的副本,可以通过手动复制或序列化实现。推荐方法:如果对象结构简单,可以手动实现深拷贝。如果对象结构复杂且支持序列化,可以使用序列化方法实现深拷贝。

weixin_44939430的博客 877

深拷贝和浅拷贝的区别和与原理

深拷贝和浅拷贝的区别和与原理

weixin_45753447的博客 1万+

C++深拷贝和浅拷贝的区别

在 C++ 中,浅拷贝和深拷贝是处理对象复制时非常关键的概念,尤其是当对象内部有指针成员指向动态分配的内存时。对于指针成员,浅拷贝只复制指针的值(即内存地址),而不复制指针所指向的数据。这意味着原对象和拷贝对象的指针成员将指向同一块内存地址。选择浅拷贝还是深拷贝取决于具体情况,但在涉及到动态内存管理的场景下,深拷贝通常是必要的,以确保数据的独立性和程序的稳定性。这样,原对象和拷贝对象的指针成员就分别指向不同的内存地址,互不干扰。当一个对象被浅拷贝时,所有的成员变量都会直接复制其值,包括指针类型的成员变量。

宁静致远的博客 1066

深拷贝和浅拷贝区别是什么?

深拷贝和浅拷贝区别是什么? 复制一个 Java 对象 浅拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。 深拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。 如何实现对象克隆? 【Java面试题与答案】整理推荐 基础与语法 集合...

ConstXiong 2万+
上一篇: SpringBoot+Minio搭建不再爆肝秃头的分布式文件服务器
下一篇: 2022最新String面试题及答案
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值