Java中的深克隆与浅克隆
浅克隆:
实现Cloneable接口即可实现,浅克隆只对象内部的基础数据类型(包括包装类)被克隆,引用数据类型(负责对象)会被使用引用的方式传递。
简单来说,就是浅克隆属性如果是复杂对象,对象是不会被复制一份的。
示例如下:
package com.comleader.utils.test;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @Author: Daisen.Z* @Date: 2023/3/10 9:53* @Version: 1.0* @Description:*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Friend {private String name;private Integer age;private String home;
}
注意: 需要重新clone方法,将方法的protected改为public
package com.comleader.utils.test;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @Author: Daisen.Z* @Date: 2023/3/10 9:53* @Version: 1.0* @Description:*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person implements Cloneable {private String name;private Integer age;private String home;private Friend friend;@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}public static void main(String[] args) throws CloneNotSupportedException {Person person_old = new Person();person_old.setName("张三");person_old.setAge(18);person_old.setHome("chengdu");person_old.setFriend(new Friend("李四",19,"chongqin"));System.out.println("初始化下的person:" + person_old);Person person_clone = (Person) person_old.clone();person_clone.setName("张武");person_clone.setAge(19);person_clone.getFriend().setAge(20);System.out.println("克隆出来的person:" + person_clone);System.out.println("修改之后的person:" + person_clone);System.out.println("修改后的原person:" + person_old);}
}
运行Person中的main方法,
观察结果可以看出,修改Person的克隆对象的friend复杂属性时,原对象包括原对象的所有克隆对象friend熟悉都会被修改。
而修改String和Integer的则互不影响。
补充知识:
clonable接口的克隆方式,相比较于new对象的方式,不需要再计算内存分布,而是直接将内存区域分配给克隆对象,在大数据量的重复对象创建时可以使用clonable来优化性能。
深克隆:
深克隆的方式只能自己重新Cloneable方法或者序列化的方式实现。
重新克隆方法的方式:
1、 Friend实现Cloneable接口,并重写clone()方法。
@Data
@NoArgsConstructor
@AllArgsConstructor
class Friend implements Cloneable{private String name;private Integer age;private String home;@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}
}
2、 更改Person中的clone()方法
@Data
@NoArgsConstructor
@AllArgsConstructor
class Person implements Cloneable{private String name;private Integer age;private String home;private Friend friend;@Overridepublic Object clone() throws CloneNotSupportedException {Person person = (Person) super.clone();person.friend = (Friend) friend.clone();return person;}
}
这样克隆时,内部复杂对象也被克隆。
通过序列化对象的方式
如果当类中的属性存在数组(数组不能实现Cloneable接口)或者属性之间的关系比较复杂时,上面的方法都不能很好的实现深克隆了。
序列化的方式是让每个类都实现Serializable接口,然后通过序列化和反序列化操作达到深克隆的目的。
package test;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.*;@Data
@NoArgsConstructor
@AllArgsConstructor
class Person implements Serializable{private String name;private Integer age;private String home;private Friend friend;}@Data
@NoArgsConstructor
@AllArgsConstructor
class Friend implements Serializable {private String name;private Integer age;private String home;}public class CloneTest {public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {Person person_old = new Person();person_old.setName("张三");person_old.setAge(18);person_old.setHome("chengdu");person_old.setFriend(new Friend("李四",19,"chongqin"));System.out.println("初始化下的person:" + person_old);ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);objectOutputStream.writeObject(person_old); // 序列化ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);Person person_clone = (Person) objectInputStream.readObject(); //反序列化person_clone.setName("张武");person_clone.setAge(19);person_clone.getFriend().setAge(20);System.out.println("克隆出来的person:" + person_clone);System.out.println("修改之后的person:" + person_clone);System.out.println("修改后的原person:" + person_old);}
}
总结:
1、 浅克隆性能相比较new会有一些提高(很小),但是编码省了很多。
2、深克隆第一种实现方式同1。
3、深克隆的第二种实现方式在数据量多的情况下性能较差,但是当类熟悉特别多、对象占用空间特别大时会有较好效果,另外通过序列化可以将对象当前的形态以文件、IO流的方式保存下来,在需要时再进行加载转换,
相关文章:

Java中的深克隆与浅克隆
浅克隆: 实现Cloneable接口即可实现,浅克隆只对象内部的基础数据类型(包括包装类)被克隆,引用数据类型(负责对象)会被使用引用的方式传递。 简单来说,就是浅克隆属性如果是复杂对象…...

如何使用MyBatis框架实现对数据库的增删查改?
目录:1.创建MyBatis项目以及如何配置2.MyBatis操作数据库的模式3.实现增删查改注意:在我们操作数据库之前,先要保证我们已经在数据库建好了一张表。创建MyBatis项目以及如何配置我们在创建项目的时候,引入MyBatis相关依赖配置数据…...

结构体内存大小
000、前言 要想计算结构体内存大小,就会涉及到一个结构体内存对齐的问题,而不是对其成员进行简单的加运算 (1)在写本博客之前 有位同学和我讨论了一个学校的题目,题目如下: 我借这道题目问了另外一位同…...

gerrit操作和jinkens编译合入代码
gerrit 先 查看自己的push 找到后添加reviewer 填写邮箱开头就可以出来 记得1 然后send 让人review 编译不过,gerrit上查看 1.是不是checkstyle问题 2.编译不过,去jinkens查看 先retrigger重新编译 如果发现多次编译失败 则要看下console output 查…...

网络工程师面试题(面试必看)(3)
作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页 前言 本系列将会提供网络工程师面试题,由多位专家整合出本系列面试题,包含上百家面试时的问题。面试必考率达到80%,本系列共86道题…...

第N次重装系统之Ubtntu
前言又一次换了服务器,由于centOS已经完成了自己的生命周期,接下来我会转去使用Ubtntu系统。当然,大部分docker命令是不会收到影响的,但是一部分安装过程可能就要重新学习了。其实这个系统也有自己的老牌包管理器apt,所…...

一个 适用 vue3 ts h5移动端 table组件
vue3-h5-table 介绍 适用于 vue3 ts 的 h5 移动端项目 table 组件 支持 左侧固定 滑动 每行点击回调 支持 指定列排序 链接 :https://github.com/duKD/vue3-h5-table 效果 props说明minTableHeight表格最小高度 可选 默认600rowNum表格显示几行 可选 默认 6he…...
Vue.js 生产打包上线实战
项目管理后台采用Vue.js 架构,开发完毕后设计到打包上传到服务器发布。 发布成功后,总结出主要要决绝两个主要问题: 1.打包前,环境设置 2.上传到服务器,直接放在Tomcat中出现跨域访问问题。 此次项目实际处理方法为…...
C语言指针的算术运算
C语言指针的算术运算 C语言中,指针是一种非常重要的数据类型。除了可以指向特定的内存地址外,指针还可以进行算术运算。指针的算术运算包括加、减、比较等操作,下面我们将详细介绍这些运算符的使用方法,并提供实际的示例。 指针…...

快速排序/快速选择算法
一.快速排序 1.基本介绍 快速排序(Quicksort〉是对冒泡排序的一种改进,都属于交换排序。基本思想是:通过一趟排序将要排序的数据分割成独立的两部分(每次选择中轴值),中轴值左边的元素小于中轴值,中轴值右边的元素全部大于中轴值(但不要求有序)&#x…...

【数据结构初阶】单链表面试题|内含链表带环问题
目录 前言 链表面试题 1. 删除链表中等于给定值 val 的所有节点。oj链接 2.反转一个单链表。oj链接 3. 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。oj链接 4. 输入一个链表,…...

一文解析ethtool 命令的使用
命令简介 ethtool命令用于查询和控制网络设备驱动程序和硬件设置,尤其是有线以太网设备,devname网卡的名称。网卡就像是交换机的一个端口,正常使用我们只是配置网卡IP地址等信息,网卡的速率、双工模式等我们并不关心。通过ethtoo…...

深度学习训练营之yolov5训练自己的数据集
深度学习训练营之训练自己的数据集原文链接环境介绍准备好数据集划分数据集运行voc_train.py遇到问题完整代码创建new_data.yaml文件模型训练时遇到的报错模型训练结果可视化参考链接原文链接 🍨 本文为🔗365天深度学习训练营 中的学习记录博客…...
Java中的AQS
文章目录什么是AQSAbstractQueuedSynchronizer方法解析自旋与阻塞ReentrantLock,Semaphore以及CountDownLatch对比ReentrantLock实现原理原理ReentrantLock源码中compareAndSetState的方法Semaphore实现原理CountDownLatch实现原理什么是AQS AQS是Java中的一个抽象…...

Spring——案例-业务层接口执行效率和AOP通知获取数据+AOP总结
执行时间获取:记录开始时间和结束时间,取差值。 这里使用环绕通知来实现。 环境准备: 项目文件结构: 业务层接口和实现类: 数据层: 采用mybatis注解开发,这里没有实现类,直接在接口方法里面实现映射。 domain层: 实现了数据库里面每一个…...

国外SEO舆情处理最佳黄金时间
在国外市场,SEO(搜索引擎优化)的舆情处理是非常重要的,因为它可以帮助提高网站的排名和流量,并且建立品牌的声誉和信誉。 然而,在什么时间进行舆情处理是一个值得探讨的问题。 在本文中,我们将…...

ROC和AUC
目录 ROC AUC ROC ROC曲线是Receiver Operating Characteristic Curve的简称,中文名为"受试者工作特征曲线"。ROC曲线的横坐标为假阳性率(False Postive Rate, FPR);纵坐标为真阳性率(True Positive Rate, TPR).FPR和TPR的计算方法分别为 F…...
Dopamine-PEG-cRGD,DOPA-PEG-cRGD,多巴胺-聚乙二醇-crgd细胞穿膜肽
名称:多巴胺-聚乙二醇-cRGD穿膜肽,多巴胺-聚乙二醇-crgd细胞穿膜肽英文名称:Dopamine-PEG-cRGD,DOPA-PEG-cRGD规格:50mg,100mg,150mg(根据要求可定制)描述:cRGD多肽序列: cyclo(RGDfK)外 观 : 半固体或固体,取决于分子量。溶解性:…...

动态规划回文子串
647. 回文子串方法:双指针回文子串有长度为奇数和偶数两种,extend(s, i, i, n); extend(s, i, i 1, n);就分别对应长度为奇数和偶数的情况class Solution { private:int extend(const string& s, int i, int j, int n) {int res 0;while (i > 0…...

windows 域控提权CVE-2014-6324CVE-2020-1472CVE-2021-42287CVE-2022-26923
一、CVE-2014-6324复现 环境:god.org域,两台主机,一台win2008域控,另一台web服务器win2008 工具:ms14-068.exe(漏洞exp) mimikatz psexec 利用条件: 1.域用户账号密码 2.获得一台主机权限(本地administ…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...