深拷贝和浅拷贝
目录
一.Java的Cloneable和clone()方法
1.Object类中的clone()
2.实现Cloneable接口的类
3.通过clone()生成对象的特点
二.深拷贝和浅拷贝
1.浅拷贝
2.深拷贝
3.实现深拷贝的两种方法
1.一种是递归的进行拷贝
2.Json字符串的方式进行深拷贝
一.Java的Cloneable和clone()方法
1.Object类中的clone()
以下是Java中Object类中clone()方法,我们可以看到clone()方法是没有方法体的,因为clone是一个native类型的代码,具体的代码实现在JVM的c++代码中实现,Java只是调用.

2.实现Cloneable接口的类
以下是Cloneable接口的内容,我们可以看到这个接口里面并没有实际的说明内容,这个接口的实现表示实现的类重写了clone()方法,可以进行对象的克隆.

现在我们实现Cloneable接口来创建一个类,这个类重写了clone(),并且根据重写的规则,这个方法的修饰必须比protected的权限更大,因此可以使用public方法,而且Object类中返回值是Object,我们这里重写的返回值可以为Dog,因为重写的规则规定返回值必须是instanceof Object,所以返回值可以为Dog.
public class Dog implements Cloneable{String name;int age;public Dog() {}public Dog(String name, int age) {this.name = name;this.age = age;}@Overridepublic Dog clone() throws CloneNotSupportedException {return (Dog)super.clone();}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", age=" + age +'}';}
}
现在我们尝试用Dog类中的clone方法来克隆一个完全一样的对象
public static void main(String[] args) throws CloneNotSupportedException {Dog dog1 = new Dog("张选宁", 2);Dog dog2 = dog1.clone();System.out.println(dog1);System.out.println(dog2);System.out.println(dog1==dog2);}
现在我们来思考一个问题,dog1和dog2是否指向的是同一个对象呢?我们有什么方法来验证是否为同一个对象呢?
这里提供两种方法来判断
- 使用==号来进行判断
//"==" 比较的是两个引用是否指向同一个对象
System.out.println(dog1==dog2);//false - 修改一个对象的属性,检查另一个对象的属性是否发生改变
dog1.name="薛程朗";System.out.println(dog1.name); //薛程朗System.out.println(dog2.name); //张选宁
因此我们从以上两个结果可以判断出,clone()方法产生的对象是指向不同引用的.
3.通过clone()生成对象的特点
上面我们通过两个结果已经总结出来了:clone()方法产生的对象是指向不同引用的.现在我们来具体的理解以下这两个对象.
根据下面两个图我们可以很直观的看出,这两个对象的地址不一样(也就是引用不一样),当改变一个对象的属性值的时候,另一个是不会发生改变的,clone()只是产生了一个属性相同的另一个对象

那么我们再来思考一个问题 ,如果这个类中包含了其他类型的对象,这个时候这个对象该如何拷贝呢?这就引出了我们的深拷贝和浅拷贝的概念了.
二.深拷贝和浅拷贝
以下是一个包含其他对象的类
public class Person implements Cloneable {String name;//包含了其他类型的对象Dog dog;public Person() {}@Overridepublic Person clone() throws CloneNotSupportedException {return (Person) super.clone();}public Person(String name, Dog dog) {this.name = name;this.dog = dog;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", dog=" + dog +'}';}
}
1.浅拷贝
接下来我们来验证是否克隆person1对象的时候,是否会将Person类中的Dog对象重现创建对象,还是仅仅是引用的复制(也就是地址相同的对象(同一个对象))
public static void main(String[] args) throws CloneNotSupportedException {Person person1 = new Person("czj", new Dog("张选宁", 3));Person person2 = person1.clone();System.out.println(person1.dog==person2.dog);//tureperson1.dog.name="薛程朗";System.out.println(person1.dog.name);//薛程朗System.out.println(person2.dog.name);//薛程朗}
通过验证我们可以很清楚的看到仅仅是引用的复制,本质上里面的dog对象还是同一个对象,形象一点来说,也就是一个人,通过克隆技术又克隆出来了一个一模一样的人,但他们拥有的狗还是同一个狗.
接下来我们还是通过画图来明确这种拷贝方式的原理

这就是浅拷贝,只是将对象里面的对象引用进行了简单的拷贝,并没有将里面的对象进行new新建
接下来是网络上的定义:
浅拷贝是指只复制了对象的引用,新对象和原对象引用的是同一个对象。因此,当修改其中一个对象时,另一个对象也会受到影响。浅拷贝通常只能复制基本数据类型和对其他对象的引用,而不能复制其所引用的对象本身。
2.深拷贝
深拷贝其实就是不仅将需要克隆的对象进行拷贝了,也将对象里面的对象也进行了重新的拷贝.

这只是简单举例,不论有多少个对象,都会进行一一的进行拷贝处理,这种方法就叫做深拷贝.
接下来是网络上的定义:
深拷贝则是指复制了对象本身,而不仅仅是对象的引用。因此,新对象和原对象在内存中拥有不同的地址,彼此之间没有任何关联。深拷贝通常能够完全复制原对象,包括所有的属性和引用对象,因此比浅拷贝更加安全和可靠。
3.实现深拷贝的两种方法
1.一种是递归的进行拷贝
具体应该将Person类中的clone()方法进行如下的修改
@Overridepublic Person clone() throws CloneNotSupportedException {Person person=(Person) super.clone();Dog dog1 = person.dog.clone();person.dog=dog1;return person;}
但是这种方法已经是很老旧的方法了,现在计算机实现已经不采用了这种方法了,现在使用的深拷贝方法是第二种方法.
2.Json字符串的方式进行深拷贝
使用JSON字符串进行深拷贝需要以下步骤:
1.将对象转换为JSON字符串:使用JSON库,如Jackson、Gson或FastJSON,将需要拷贝的对象转换为JSON字符串。
2.将JSON字符串转换回对象:使用JSON库将JSON字符串转换回一个新的对象。
这将创建一个新的对象,其属性与原始对象相同,但是它们不会共享对象引用,而是创建新的引用。
下面是一个使用Jackson库进行深拷贝的示例代码:
import com.fasterxml.jackson.databind.ObjectMapper;public class DeepCopyUtils {private static final ObjectMapper objectMapper = new ObjectMapper();public static <T> T deepCopy(T object) throws Exception {String jsonString = objectMapper.writeValueAsString(object);return objectMapper.readValue(jsonString, (Class<T>) object.getClass());}
}
在这个示例代码中,我们使用Jackson的ObjectMapper类将对象转换为JSON字符串,并将其转换回新的对象。
相关文章:
深拷贝和浅拷贝
目录 一.Java的Cloneable和clone()方法 1.Object类中的clone() 2.实现Cloneable接口的类 3.通过clone()生成对象的特点 二.深拷贝和浅拷贝 1.浅拷贝 2.深拷贝 3.实现深拷贝的两种方法 1.一种是递归的进行拷贝 2.Json字符串的方式进行深拷贝 一.Java的Cloneable和clone…...
【回眸】ChatGPT Plus(GPT4体验卡)
前言 没忍住诱惑,开了个GPT4.0的会员,给大家表演一波 开通成功 开始问问题 写一个CNN疲劳驾驶监测代码,要求{使用Python语言,使用包,能成功运行,需要调用电脑摄像头,要求GUI界面有一些参数…...
走进小程序【七】微信小程序【常见问题总结】
文章目录🌟前言🌟小程序登录🌟unionid 和 openid🌟关键Api🌟登录流程设计🌟利用现有登录体系🌟利用OpenId 创建用户体系🌟利用 Unionid 创建用户体系🌟授权获取用户信息流…...
光电隔离转换器 直流信号放大器 导轨安装DIN11 IPO OC系列
概述: 导轨安装DIN11 IPO OC系列模拟信号隔离放大器是一种将输入信号隔离放大、转换成按比例输出的直流信号混合集成厚模电路。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等需要直流信号隔离测控的行业。此系列产品内部采用了线性光电隔离技术相…...
语聊房app的开发以及运营思路
语聊房app是一种基于实时语音交流的社交应用,用户可以通过该应用结识新朋友、交流经验、分享兴趣爱好等,因此备受年轻用户的青睐。以下是语聊房app的开发以及运营思路: 一、开发思路 功能设计 语聊房app的核心功能是实时语音聊天࿰…...
目标检测基础之IOU计算
目标检测基础之IOU计算概念理解——什么是IOUdemo后记概念理解——什么是IOU IOU 交并比(Intersection over Union),从字面上很容易理解:计算交集在并集的比重。从网上截张图看看 IOUA∩BA∪BIOU \frac{A \cap B}{A \cup B} IO…...
从spring boot泄露到接管云服务器平台
0x1前言 在打野的时候意外发现了一个站点存在spring boot信息泄露,之前就有看到一些文章可以直接rce啥的,今天刚好试试。通过敏感信息发现存在accesskey泄露,就想直接通过解密,获取敏感信息,接管云平台。 首先说下这个…...
大数据技术——spark集群搭建
目录 spark概述 spark集群搭建 1.Spark安装 2.环境变量配置 3.Spark集群配置 4.启动Spark集群 存在问题及解决方案 请参考以下文章 spark概述 Spark是一个开源的大数据处理框架,它可以在分布式计算集群上进行高效的数据处理和分析。Spark的特点是速度快、易…...
嵌入式学习笔记汇总
本文整理STM32、STM8和uCOS-III的所有文章链接。 STM32学习笔记目录 源码:mySTM32-learn STM32学习笔记(1)——LED和蜂鸣器 STM32学习笔记(2)——按键输入实验 STM32学习笔记(3)——时钟系统 …...
Python 全栈系列220 Tornado的服务搭建
说明 想法变的真快 本来是没打算用Tornado的,主要是想节约时间。但是现在看来不用还是不行:目前用gevent flask部署的时候,启动多核的worker似乎存在问题。 另外,有很多内部基础的数据服务,其实并不需要flask的各种组…...
ESXi安装CentOS
ESXi安装 参考:https://blog.csdn.net/tongxin_tongmeng/article/details/129466704 CentOS安装 镜像:http://mirrors.aliyun.com/centos/7/isos/x86_64-->CentOS-7-x86_64-DVD-2009.iso CentOS配置 FinalShell连接 ESXi简介 1.ESXi是由VMware公司…...
WebTest搭建
0.前言 此框架为真实项目实战,所以有些数据不便展示,只展示架构和思想 工具:pythonseleniumddtunittest 1.架构说明 2.代码封装 Commom层 base_page.py #__author__19044168 #date2021/8/26 import logging import datetime from sele…...
什么性格的人适合报考机械类专业?(高考志愿填报选专业)
机械类专业 是指涉及机械设计、制造、加工、维护等方面的专业,是工程类专业中的一类。机械类专业的学生主要学习机械工程的基础知识,包括机械设计、力学、材料力学、热力学、流体力学等,同时也会学习机械制造、机电一体化、机器人技术等实践性…...
进程概念详解
目录 进程是什么? 描述进程:进程控制块-PCB task_struct task_struct 是什么? task_struct内容分类 组织进程 查看进程 fork创建子进程 进程状态 僵尸进程 孤儿进程 进程优先级 其他概念 进程是什么? 一般书上…...
C语言基础——指针
文章目录一、指针1.指针的意义2.指针类型表示3.一些操作3.1打印1个变量地址3.2通过地址查看改地址的内容以及修改改地址的内容3.3操作某个空间 -- 4个字节,给他赋值为100,只知道该空间的地址0x8000 00004.指针变量的定义5.指针类型的大小6.指针变量的使用6.1 指针变…...
反序列化渗透与攻防(二)之Java反序列化漏洞
Java反序列化漏洞 反序列化漏洞 JAVA反序列化漏洞到底是如何产生的? 1、由于很多站点或者RMI仓库等接口处存在java的反序列化功能,于是攻击者可以通过构造特定的恶意对象序列化后的流,让目标反序列化,从而达到自己的恶意预期行为,包括命令执行,甚至 getshell 等等。 …...
优先级队列的模拟实现(仿函数)
目录: 1.priority_queue接口的实现(先建大堆) 1.push 加 向上调整的实现 2.pop 3.迭代器区间的构造 2.仿函数 3.仿函数优化我们的优先级队列 -------------------------------------------------------------------------------------------…...
Python pandas和numpy用法参考(转)
以下是转载:Python pandas用法 - 简书介绍 在Python中,pandas是基于NumPy数组构建的,使数据预处理、清洗、分析工作变得更快更简单。pandas是专门为处理表格和混杂数据设计的,而NumPy更适合处...https://www.jianshu.com/p/840ba1…...
mysql数据库的在线数据备份与数据恢复
MySQL是一种常用的关系型数据库管理系统,它支持在线备份和恢复数据。在线备份指的是在MySQL数据库运行时备份数据,而不会中断或影响现有的数据库服务。在本文中,我们将介绍MySQL数据库的在线数据备份和恢复的原理和操作步骤。 一、备份原理 …...
Vue3自定义指令之前端水印功能实现
一、前置知识 — Vue 中的自定义指令 先来说说 vue2和vue3中自定义全局指令的区别 相同点:指令的应用场景,原理是一致的; 不同点:生命周期钩子函数名,指令定义的格式不一样。 vue2中自定义全局指令: 定义…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
