JavaSE:Clonable接口、浅拷贝与深拷贝

news2024/11/15 15:27:04

1、引言

我们在学习的数组时,就了解到了数组克隆方法,可以通过数组克隆方法来拷贝一个一模一样的数组:

那对于自定义类型中有没有克隆方法呢?答案是有的!

就让这篇文章来帮助大家学习自定义类型的拷贝!

2、自定义类型的拷贝

我们首先自定义一个学生类:

我们已知,所有的类都继承于Object类,我们可以看到Object类中也实现了clone方法:

按理说,作为子类是可以使用继承下来的clone方法的,可是当我们去使用clone方法时却发现写不出来:

那我们该如何去实现自定义类型的拷贝呢?

1. 重写clone方法

为什么要重写clone方法呢?我们先来看Object类中的clone方法:

我们发现父类中方法的权限是protected,那我们就需要利用super关键字来调用父类的clone方法,所以我们重写clone方法:

这时我们发现我们已经可以写出了clone方法:

可是代码仍然报错,那是因为方法的返回值是Object类型:

2. 强制类型转换为子类类型

我们发现仍然报错,那是因为我们没有抛出异常。

3. 抛出异常

我们可以发现,在我们利用Idea快速重写了clone方法后,重写方法抛出了异常:

那我们也需要在main方法抛出异常:

我们这时发现,没有了报错,那我们来运行:

却出现了不支持克隆的异常,因为我们还差最后一步,实现Cloneable接口

4. 实现Clonable接口

当我们点进去查看这个接口时,我们发现什么方法都没有:

这表面,Cloneable是一个空接口

那有人就有疑问了:“什么都没有那空接口是来干嘛来了?”

答:空接口也叫做标记接口,表示当前类是可以被克隆的!!!

总结步骤:

1. 重写clone方法

2. 强制类型转换为子类类型

3. 抛出异常

4. 实现Clonable接口

在完成以上步骤后,我们就可以成功的拷贝出一个对象:

3、浅拷贝

当我们在自定义Student类中再定义一个自定义类的对象后,

我们再次进行拷贝,并修改拷贝的student2对象的moneyNum值,我们会发现,student1的moneyNum也被改变了:

这是因为,原有的student1和拷贝后的student2中的money引用指向的是同一个区域,只要一个改变,另外一个就会跟着改变,我们可以参考下图理解:

我们并没有把Money对象中的moneyNum也拷贝一份,

也就是说,我们只拷贝了Student对象,而没有拷贝Money对象,这样的拷贝称为浅拷贝!!!

那如何做到修改student2的moneyNum值而不影响student1中的moneyNum值呢?

答:那就需要完成深拷贝

4、深拷贝

其实完成深拷贝也是很简单的,我们只需要额外的完成对Money的拷贝就可以了

为了完成对自定义类型Money的拷贝,也需要根据上面讲到的步骤完成(在此不再列出细节):

然后,我们只需在Student类中重写的clone方法上做处理即可:

(我们将浅拷贝得到的tmp中Money对象也完成一份拷贝即可)

这时我们发现,修改student2的moneyNum值便不会影响到student1了,也就是说,我们成功的将Money对象也拷贝了一份,完成了深拷贝!!!

OK~本次博客到这里就结束了,

感谢大家的阅读~欢迎大家在评论区交流问题~

如果博客出现错误可以提在评论区~

创作不易,请大家多多支持~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684917.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于深度学习的表情识别系统

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着人工智能技术的快速发展,表情识别成为了人机交互领域的一个研究热点。表情识别技术旨…

docker redis 持久化

1、拉取redis镜像 docker pull redis:latest 2、 mkdir /data/redis 3、填充redis.conf文件及根据需求修改相应的配置 •通过官网地址找到对应版本的配置文件 •将配置信息复制到redis.conf中 •常见的修改配置 https://redis.io/docs/latest/operate/oss_and_stack/managem…

K8s 高级调度

文章目录 K8s 高级调度CronJobinitContainerTaint 和 Toleration污点(Taint)容忍(Toleration) AffinityNodeAffinityPodAnffinity 和 PodAntiAffinity 总结 K8s 高级调度 CronJob 在 k8s 中周期性运行计划任务,与 li…

获取支持Windows7的最新Edge离线版本

从110版本开始,微软Edge和谷歌停止了对Win7、Win8/8.1的支持,后续又发布了几版安全更新,截止目前为止,能支持Win7的版本是 109.0.1518.140。 如果你想用最新版本谷歌浏览器,可以考虑下Supermium,这个浏览器…

Flask CORS: 解决跨域资源共享问题的利器

文章目录 安装和启用 CORS配置 CORS拓展 在本文中,我们介绍了如何使用 Flask-CORS 扩展来解决跨域问题。Flask-CORS 是一个方便的工具,可以帮助我们轻松地实现跨域资源共享支持。 安装和启用 CORS 要开始使用 Flask-CORS,我们需要先安装它。…

一些常见的程序设计问题

秒杀 redis缓存库存 1.判断库存名额是否充足,2.进行扣减 为了防止超卖,必须保证这两部的原子性 库存扣减后发送mq消息,去异步执行创建订单流程,创建订单失败会造成少卖。可加重试机制,对多次重试依旧失败的&#xff…

react 函数组件 开发模式默认被渲染两次

这是 React 刻意为之,函数式组件应当遵从函数式编程风格,每次执行应该是无副作用的(no sideEffect),在 dev 下多次渲染组件,是为了防止开发者写出有问题的代码。 用 React 写函数组件,如何避免重复渲染? -…

【BUG】流式响应requests得到: ping - 和时间戳

前情提要 运行Langchain-Chatchat项目,使用自定义请求访问API Server流式输出 报错展示 b: ping - 2024-05-22 00:46:04.83252000:00\r\n\r\n报错原因 这通常是由于 Server-Sent Events (SSE) 实现中使用的“心跳”机制,以确保连接保持活跃。一些 SSE…

使用python实现socket进行消息传输-demo

Socket 是什么 Socket 是一种在计算机网络中用于实现进程间通信的一种机制。它是网络编程中的重要概念,通过它可以在不同的计算机之间进行数据传输和通信。Socket 可以用于实现各种网络应用,包括客户端-服务器模型、P2P 应用等。基本上,Sock…

新零售数据中台:构建零售业高效率、智能化的数据处理平台_光点科技

随着互联网技术的快速发展和移动支付、大数据等技术的广泛应用,零售行业已经逐渐从传统零售向新零售模式转变。在这个变革的时代背景下,新零售数据中台应运而生,它作为零售行业数据资源的整合与智能分析的核心载体,成为推动零售行…

基于消息中间件的异步通信机制在系统解耦中的优化与实现

✨✨谢谢大家捧场,祝屏幕前的小伙伴们每天都有好运相伴左右,一定要天天开心哦!✨✨ 🎈🎈作者主页: 喔的嘛呀🎈🎈 ✨✨ 帅哥美女们,我们共同加油!一起进步&am…

重生之我要精通JAVA--第五周笔记

文章目录 APIJDK7时间Date时间类CalendarSimpleDateFormat 类SimpleDateFormat 类作用 JDK8时间Zoneld时区 包装类Integer成员方法 Arrays Lambda表达式标准格式注意点好处省略写法 集合进阶Collection迭代器遍历Collection集合获取迭代器Iterator中的常用方法细节注意点 增强f…

【软考中级 软件设计师】计算机网络和安全

计算机网络和安全是软件设计师(软考中级)考试中的重要组成部分,它涵盖了网络基础、网络协议、网络架构、网络安全等多个方面。以下是一些核心概念和要点, 计算机网络基础 OSI七层模型:物理层、数据链路层、网络层、传…

【20天拿下Pytorch:Day 7】Dataset和DataLoader

文章目录 1. Dataset和DataLoader概述1.1 概要1.2 获取一个batch数据的步骤1.3 Dataset和DataLoader的功能分工1.4 Dataset和DataLoader的主要接口 2. 使用Dataset创建数据集2.1 根据Tensor创建数据集2.2 根据图片目录创建图片数据集2.3 创建自定义数据集 3. 使用DataLoader加载…

C++ TCP发送Socket数据

DEVC需要加入ws2_32库 #include <iostream> #include <winsock2.h>#pragma comment(lib, "ws2_32.lib")void sendData(const char* ip, int port, const char* data) {WSADATA wsaData;SOCKET sockfd;struct sockaddr_in server_addr;// 初始化Winsock…

打气球小游戏

1.气球往上飘 我们声明两个符号常量来作为窗体的长和宽,接着就是常规操作 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600#include<easyx.h> #include<stdio.h> int main() {initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);setbkcolor(WHITE);cleardevice();get…

php部分特性漏洞学习

php部分函数漏洞学习 简单总结一些我遇到的ctf中的php的一些函数或特性的漏洞&#xff0c;我刷题还是太少了&#xff0c;所以很多例子来自ctfshow&#xff0c;以后遇到相关赛题再更新 1.MD5和其他hash 弱类型比较 php中&#xff0c;有两中判断相等的符号&#xff0c;和&…

【Linux】进程信号及相关函数/系统调用的简单认识与使用

文章目录 前言一、相关函数/系统调用1. signal2. kill3. abort (库函数)4. raise (库函数)5. alarm 前言 现实生活中, 存在着诸多信号, 比如红绿灯, 上下课铃声…我们在接收到信号时, 就会做出相应的动作. 对于进程也是如此的, 进程也会收到来自 OS 发出的信号, 根据信号的不同…

树莓派 Raspberry Pi M.2 HAT+ 现已发售!原理图流出!

​Raspberry Pi M.2 HAT 使您能够将 M.2 M-key 外设&#xff08;如 NVMe 驱动器和人工智能加速器&#xff09;连接到 Raspberry Pi 5。它能够提供与这些外设之间的快数据传输&#xff08;高达 500 MB/s&#xff09;&#xff0c;现在就可以从树莓派的授权经销商网络购买&#xf…

智能网关和交换机在智慧路灯杆上的用途差别

智慧路灯杆是智能城市建设中的一个重要组成部分&#xff0c;它整合了智能照明、视频监控、交通管理、环境监测、网络覆盖、信息发布、一键告警等多种功能。针对智慧路灯杆的使用场景&#xff0c;智能网关和交换机各自发挥着不同的作用&#xff0c;并且拥有各自的优缺点&#xf…