当前位置: 首页 > news >正文

深拷贝和浅拷贝

目录

一.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是否指向的是同一个对象呢?我们有什么方法来验证是否为同一个对象呢?

这里提供两种方法来判断

  1. 使用==号来进行判断

            //"==" 比较的是两个引用是否指向同一个对象
            System.out.println(dog1==dog2);//false

  2.  修改一个对象的属性,检查另一个对象的属性是否发生改变
        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体验卡)

前言 没忍住诱惑&#xff0c;开了个GPT4.0的会员&#xff0c;给大家表演一波 开通成功 开始问问题 写一个CNN疲劳驾驶监测代码&#xff0c;要求{使用Python语言&#xff0c;使用包&#xff0c;能成功运行&#xff0c;需要调用电脑摄像头&#xff0c;要求GUI界面有一些参数…...

走进小程序【七】微信小程序【常见问题总结】

文章目录&#x1f31f;前言&#x1f31f;小程序登录&#x1f31f;unionid 和 openid&#x1f31f;关键Api&#x1f31f;登录流程设计&#x1f31f;利用现有登录体系&#x1f31f;利用OpenId 创建用户体系&#x1f31f;利用 Unionid 创建用户体系&#x1f31f;授权获取用户信息流…...

光电隔离转换器 直流信号放大器 导轨安装DIN11 IPO OC系列

概述&#xff1a; 导轨安装DIN11 IPO OC系列模拟信号隔离放大器是一种将输入信号隔离放大、转换成按比例输出的直流信号混合集成厚模电路。产品广泛应用在电力、远程监控、仪器仪表、医疗设备、工业自控等需要直流信号隔离测控的行业。此系列产品内部采用了线性光电隔离技术相…...

语聊房app的开发以及运营思路

语聊房app是一种基于实时语音交流的社交应用&#xff0c;用户可以通过该应用结识新朋友、交流经验、分享兴趣爱好等&#xff0c;因此备受年轻用户的青睐。以下是语聊房app的开发以及运营思路&#xff1a; 一、开发思路 功能设计 语聊房app的核心功能是实时语音聊天&#xff0…...

目标检测基础之IOU计算

目标检测基础之IOU计算概念理解——什么是IOUdemo后记概念理解——什么是IOU IOU 交并比&#xff08;Intersection over Union&#xff09;&#xff0c;从字面上很容易理解&#xff1a;计算交集在并集的比重。从网上截张图看看 IOUA∩BA∪BIOU \frac{A \cap B}{A \cup B} IO…...

从spring boot泄露到接管云服务器平台

0x1前言 在打野的时候意外发现了一个站点存在spring boot信息泄露&#xff0c;之前就有看到一些文章可以直接rce啥的&#xff0c;今天刚好试试。通过敏感信息发现存在accesskey泄露&#xff0c;就想直接通过解密&#xff0c;获取敏感信息&#xff0c;接管云平台。 首先说下这个…...

大数据技术——spark集群搭建

目录 spark概述 spark集群搭建 1.Spark安装 2.环境变量配置 3.Spark集群配置 4.启动Spark集群 存在问题及解决方案 请参考以下文章 spark概述 Spark是一个开源的大数据处理框架&#xff0c;它可以在分布式计算集群上进行高效的数据处理和分析。Spark的特点是速度快、易…...

嵌入式学习笔记汇总

本文整理STM32、STM8和uCOS-III的所有文章链接。 STM32学习笔记目录 源码&#xff1a;mySTM32-learn STM32学习笔记&#xff08;1&#xff09;——LED和蜂鸣器 STM32学习笔记&#xff08;2&#xff09;——按键输入实验 STM32学习笔记&#xff08;3&#xff09;——时钟系统 …...

Python 全栈系列220 Tornado的服务搭建

说明 想法变的真快 本来是没打算用Tornado的&#xff0c;主要是想节约时间。但是现在看来不用还是不行&#xff1a;目前用gevent flask部署的时候&#xff0c;启动多核的worker似乎存在问题。 另外&#xff0c;有很多内部基础的数据服务&#xff0c;其实并不需要flask的各种组…...

ESXi安装CentOS

ESXi安装 参考&#xff1a;https://blog.csdn.net/tongxin_tongmeng/article/details/129466704 CentOS安装 镜像&#xff1a;http://mirrors.aliyun.com/centos/7/isos/x86_64-->CentOS-7-x86_64-DVD-2009.iso CentOS配置 FinalShell连接 ESXi简介 1.ESXi是由VMware公司…...

WebTest搭建

0.前言 此框架为真实项目实战&#xff0c;所以有些数据不便展示&#xff0c;只展示架构和思想 工具&#xff1a;pythonseleniumddtunittest 1.架构说明 2.代码封装 Commom层 base_page.py #__author__19044168 #date2021/8/26 import logging import datetime from sele…...

什么性格的人适合报考机械类专业?(高考志愿填报选专业)

机械类专业 是指涉及机械设计、制造、加工、维护等方面的专业&#xff0c;是工程类专业中的一类。机械类专业的学生主要学习机械工程的基础知识&#xff0c;包括机械设计、力学、材料力学、热力学、流体力学等&#xff0c;同时也会学习机械制造、机电一体化、机器人技术等实践性…...

进程概念详解

目录 进程是什么&#xff1f; 描述进程&#xff1a;进程控制块-PCB task_struct task_struct 是什么&#xff1f; task_struct内容分类 组织进程 查看进程 fork创建子进程 进程状态 僵尸进程 孤儿进程 进程优先级 其他概念 进程是什么&#xff1f; 一般书上…...

C语言基础——指针

文章目录一、指针1.指针的意义2.指针类型表示3.一些操作3.1打印1个变量地址3.2通过地址查看改地址的内容以及修改改地址的内容3.3操作某个空间 -- 4个字节,给他赋值为100&#xff0c;只知道该空间的地址0x8000 00004.指针变量的定义5.指针类型的大小6.指针变量的使用6.1 指针变…...

反序列化渗透与攻防(二)之Java反序列化漏洞

Java反序列化漏洞 反序列化漏洞 JAVA反序列化漏洞到底是如何产生的? 1、由于很多站点或者RMI仓库等接口处存在java的反序列化功能,于是攻击者可以通过构造特定的恶意对象序列化后的流,让目标反序列化,从而达到自己的恶意预期行为,包括命令执行,甚至 getshell 等等。 …...

优先级队列的模拟实现(仿函数)

目录&#xff1a; 1.priority_queue接口的实现&#xff08;先建大堆&#xff09; 1.push 加 向上调整的实现 2.pop 3.迭代器区间的构造 2.仿函数 3.仿函数优化我们的优先级队列 -------------------------------------------------------------------------------------------…...

Python pandas和numpy用法参考(转)

以下是转载&#xff1a;Python pandas用法 - 简书介绍 在Python中&#xff0c;pandas是基于NumPy数组构建的&#xff0c;使数据预处理、清洗、分析工作变得更快更简单。pandas是专门为处理表格和混杂数据设计的&#xff0c;而NumPy更适合处...https://www.jianshu.com/p/840ba1…...

mysql数据库的在线数据备份与数据恢复

MySQL是一种常用的关系型数据库管理系统&#xff0c;它支持在线备份和恢复数据。在线备份指的是在MySQL数据库运行时备份数据&#xff0c;而不会中断或影响现有的数据库服务。在本文中&#xff0c;我们将介绍MySQL数据库的在线数据备份和恢复的原理和操作步骤。 一、备份原理 …...

Vue3自定义指令之前端水印功能实现

一、前置知识 — Vue 中的自定义指令 先来说说 vue2和vue3中自定义全局指令的区别 相同点&#xff1a;指令的应用场景&#xff0c;原理是一致的&#xff1b; 不同点&#xff1a;生命周期钩子函数名&#xff0c;指令定义的格式不一样。 vue2中自定义全局指令&#xff1a; 定义…...

文章生成器写出来的原创文章

文章生成机器人 文章生成机器人是一种基于人工智能技术和自然语言处理算法的程序&#xff0c;可以自动地生成高质量、原创的文章。 文章生成机器人的优点如下&#xff1a; 提高工作效率&#xff1a;文章生成机器人能够在较短的时间内自动帮助用户生成大量的文章&#xff0c;提…...

2023年全国最新高校辅导员精选真题及答案49

百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 76.气质就是我们平常所说的脾气秉性。 答案&#xff1a;正确 77.社会心理通常是通过社会…...

【STL十】关联容器——set容器、multiset容器

【STL十】关联容器——set容器、multiset容器一、set简介二、头文件三、模板类四、set的内部结构五、成员函数1、迭代器2、元素访问3、容量4、修改操作~~5、操作~~5、查找6、查看操作六、demo1、查找find2、修改操作insert3、修改操作erase、clear七、multisetset和multiset会根…...

什么是Node.js

文章目录什么是Node.js简介常用命令Node内置模块Node.js和JavaScript的区别什么是Node.js 简介 Node.js是一个基于Chrome V8引擎的JavaScript运行环境。它允许开发者使用JavaScript编写服务器端代码&#xff0c;而不仅仅是浏览器端的代码。Node.js的出现使得JavaScript可以在…...

比GPT-4 Office还炸裂,阿里版GPT全家桶来袭

疯狂3月的那一天&#xff0c;一切还历历在目。 微软突然在发布会上放出大招&#xff0c;用Microsoft 365 Copilot掀起了办公软件革命。 而今天&#xff0c;阿里也放出一枚重磅炸弹——阿里版的Copilot也要来了&#xff01; 并且比微软更彻底的是&#xff0c;阿里全系产品也都…...

mysql 建表约束

主键约束 -- 主键约束 -- 使某个字段不重复且不得为空&#xff0c;确保表内所有数据的唯一性。 CREATE TABLE user (id INT PRIMARY KEY,name VARCHAR(20) );-- 联合主键 -- 联合主键中的每个字段都不能为空&#xff0c;并且加起来不能和已设置的联合主键重复。 CREATE TABLE …...

在Vue项目中使用tinymce富文本编辑器

TinyMC编辑器简介 TinyMCE是一款易用、且功能强大的所见即所得的富文本编辑器。跟其他富文本编辑器相比&#xff0c;有着丰富的插件&#xff0c;支持多种语言&#xff0c;能够满足日常的业务需求并且免费。 TinyMCE的优势&#xff1a; 开源可商用&#xff0c;基于LGPL2.1 插…...

GPT-4 和ChatGPT API的定价分析

OpenAI发布了他们的ChatGPT新机器学习模型GPT-4。GPT-4是GPT-3的一大进步&#xff0c;GPT-3是当前ChatGPT免费版本(GPT 3.5 Turbo)所运行的模型的基础&#xff0c;今天我们也来凑个热点&#xff0c;研究一下它们的定价 GPT-4新的功能 GPT-4可以在对话中使用图像&#xff0c;并…...

基于html+css的盒子展示2

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…...

【持续更新篇】SLAM视觉特征点汇总+ORB特征点+VINS前端

Harris角点 opencv函数 cornerHarris提取输入图像的Harris角点 检测原理 检测思想&#xff1a;使用一个固定窗口在图像上进行任意方向的滑动&#xff0c;对比滑动前后的窗口中的像素灰度变化程度&#xff0c;如果存在任意方向上的滑动&#xff0c;都有较大灰度变化&#xf…...