Java:接口应用(Clonable 接口和深拷贝)

目录

  • 1.引例
  • 2.Object中clone方法的实现
  • 3.Cloneable接口讲解
  • 4.深拷贝和浅拷贝
    • 4.1浅拷贝
    • 4.2深拷贝

1.引例

Java 中内置了一些很有用的接口, Clonable 就是其中之一.
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”. 但是要想合法调用 clone 方法。必须要先实现 Clonable 接口。 否则就会抛出异常.
( CloneNotSupportedException )
如下所示,当我们要克隆一个我们已经实例化的Student类该怎么去实现呢?

class Student{private int age;public Student(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"age=" + age +'}';}
}
public class Test {public static void main(String[] args) {Student student1=new Student(10);}
}

首先,我们要知道Java中所有的类都继承Object类
当我们找到Object类的原码时,我们会发现一个clone()方法
在这里插入图片描述
那我们可能会想:既然所有的类都继承Object类,那当我们要克隆student1,直接通过student1.clon去调用这个克隆方法来实现克隆操作,但是真正去实现的时候就会发现以下问题:我们找不到这个方法。
在这里插入图片描述

2.Object中clone方法的实现

在这里插入图片描述
为什么找不到Object类中的clone方法呢,通过原码我们能看到Object类中clone方法由protected修饰
protected:同包下可以访问,不同包只有子类能访问
所以我们进行第一步,方法的重写
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重写后可以引用clone方法了,但是我们会发现还是报错,因为引用的clone方法是父类的。
当我们要将它传给子类我们就要进行第二步:强制转换
在这里插入图片描述
强制转换后还是报错,这样我们就需要进行第三步:(涉及异常知识,后面再进行补充)

public class Test {public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student(10);Student student2=(Student)student1.clone();System.out.println(student2.toString());}
}

在这里插入图片描述

这时解决完异常问题后,当我们真正进行运行时还是会报错,这样我们就要进行第四步:实现Cloneable接口
在这里插入图片描述
在这里插入图片描述
完成以上四步后就可以成功完成clone了。
完整代码

class Student implements Cloneable{private int age;public Student(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Test {public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student(10);Student student2=(Student)student1.clone();System.out.println(student2.toString());}
}

输出结果
在这里插入图片描述

3.Cloneable接口讲解

通过原码可以发现Cloneable里面什么也没有,是一个空接口(也叫标记接口)。
在这里插入图片描述

4.深拷贝和浅拷贝

4.1浅拷贝

class Money{public double money=12.5;
}
class Student implements Cloneable{private int age;public Money m=new Money();public Student(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Test {public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student(10);Student student2=(Student)student1.clone();System.out.println(student2.toString());}
}

我们在上面的代码中加入了Money类并且在Student类中实例化了一个Money。
这时我们再进行克隆如下图所示
在这里插入图片描述
当我们对student1进行可能时money并没有也克隆一份,这样就是浅拷贝。举例如下:
在这里插入图片描述
在这里插入图片描述
我们只是改变了student2的money,但是student1的money也跟着改变了。

4.2深拷贝

class Money implements Cloneable{public double money=12.5;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
class Student implements Cloneable{private int age;public Money m=new Money();public Student(int age) {this.age = age;}@Overridepublic String toString() {return "Student{" +"age=" + age +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {Student temp=(Student)super.clone();temp.m= (Money)this.m.clone();return temp;}
}
public class Test {public static void main(String[] args) throws CloneNotSupportedException {Student student1=new Student(10);Student student2=(Student)student1.clone();System.out.println(student1.m.money);System.out.println(student2.m.money);System.out.println("================");student2.m.money=100;System.out.println(student1.m.money);System.out.println(student2.m.money);}
}

我们使Money类也重写clone方法,并对Student类中的clone方法进行了改动,来实现深拷贝
在这里插入图片描述
举例如下
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

精密电阻阻值表和电容容值表

前面2张是电阻阻值表(E-96/0603/1%) 常见贴片电容的容值表

解决windows下Qt Creator显示界面过大的问题

🐌博主主页:🐌​倔强的大蜗牛🐌​ 📚专栏分类:QT❤️感谢大家点赞👍收藏⭐评论✍️ 目录 问题描述 解决方法 1、右击此电脑--->属性 2、点击高级系统设置--->点击环境变量 3、 找到系…

【美团笔试题汇总】2023-08-26-美团春秋招笔试题-三语言题解(CPP/Python/Java)

🍭 大家好这里是KK爱Coding ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新小米近期的春秋招笔试题汇总~ 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢&#x1f…

想要安装ssh?

SSH(Secure Shell)是一种加密的网络协议,用于在不安全的网络上安全地进行远程登录和执行命令。它通过加密通信和身份验证机制,确保用户和系统之间的通信是安全的。 SSH协议的主要功能包括: 加密通信:SSH使…

虚良SEO-蜘蛛池的作用与工作原理

蜘蛛池是一种SEO优化工具,其主要作用是吸引搜索引擎蜘蛛到特定网站进行爬行和索引,从而提高网站的可见性和排名。下面分别介绍蜘蛛池的作用和工作原理。 蜘蛛池的作用: 提高网站收录: 当一个网站新发布时,或者长时间…

哈佛大学商业评论 --- 第三篇:真实世界中的增强现实

AR将全面融入公司发展战略! AR将成为人类和机器之间的新接口! AR将成为人类的关键技术之一! 请将此文转发给您的老板! --- 本文作者:Michael E.Porter和James E.Heppelmann 虽然物理世界是三维的,但大…

如何查询大数据信用报告?查询时需要注意的事项有哪些?

在数字化时代,大数据信用评分对于需要资金周转的个人或企业来说至关重要。许多机构在贷款审批过程中使用大数据信用评分作为风险控制的重要手段。因此,了解自己的大数据信用状况成为了常规操作。本文将详细介绍如何查询大数据信用报告以及查询时需要注意…

ES6: class类

类 class 面相对象class关键字创建类关于类的继承 面相对象 一切皆对象。 举例: 操作浏览器要使用window对象;操作网页要使用document对象;操作控制台要使用console对象; ES6中增加了类的概念,其实ES5中已经可以实现类…

震惊!子元素的padding/margin-top依据的是父元素的宽度!

子元素的margin-top和padding-top都是以父元素的宽度为基准 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" />…

7.java openCV4.x 入门-Mat之转换、重塑与计算

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

openEuler 22.03 SP3 安装图像桌面 UKUI

UKUI 是麒麟软件团队历经多年打造的一款 Linux 桌面&#xff0c;主要基于 GTK 和 QT 开发。与其他 UI 界面相比&#xff0c;UKUI 更加注重易用性和敏捷度&#xff0c;各元件相依性小&#xff0c;可以不依赖其他套件而独自运行&#xff0c;给用户带来亲切和高效的使用体验。 UK…

day2 | 数组 part-2 | 977 有序数组的平方、209 长度最小的子数组、59 螺旋矩阵 II

今日任务 977 有序数组的平方 (题目: . - 力扣&#xff08;LeetCode&#xff09;)209 长度最小的子数组 (题目: ​​​​​​​. - 力扣&#xff08;LeetCode&#xff09;)59 螺旋矩阵 II (题目:. - 力扣&#xff08;LeetCode&#xff09;) 有序数组的平方 (双指针) 给你一个…

如何使用 Viggle AI 生成模特动作视频

Viggle AI 是一款基于骨骼动画的 AI 工具&#xff0c;可以将图片转换为流畅且一致的角色动画。 这意味着您可以上传一张模特全身照&#xff0c;然后指定该模特要执行的动作&#xff0c;Viggle AI 会自动生成一段由该模特执行该动作的视频。 步骤 1&#xff1a;准备工作 首先&…

基于VUE实现的餐厅经营游戏项目源码

WebMOOC 餐厅游戏 项目介绍 实现了一个类游戏的餐厅经营模拟&#xff0c;涉及的前端知识有移动端 HTML 页面布局及样式实现。实现了厨师、顾客等角色的关键操作&#xff0c;完成从顾客等位、点菜、烹饪、用餐、支付的一系列状态变更的数据、信息、交互、展现的变化及处理。 …

【Redis系列】Spring Boot 集成 Redis 实现缓存功能

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

c# wpf template itemtemplate+dataGrid

1.概要 2.代码 <Window x:Class"WpfApp2.Window8"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d"http://schemas.microsoft.com/expression/blend…

SpringCloudAlibabaSeate处理分布式事务

SpringCloudAlibabaSeate处理分布式事务 1、部分面试题 微服务boot/cloud做的项目&#xff0c;你不可能只有一个数据库吧&#xff1f;那么多个数据库之间如何处理分布式事务的&#xff1f; 一个场景&#xff1a;在订单支付成功后&#xff0c;交易中心会调用订单中心的服务把订…

导入项目运行后,报错java: Cannot find JDK ‘XX‘ for module ‘XX‘

解决方案&#xff1a; 1、删除.idea和.iml文件 2、右击此module&#xff0c;点击 Open Module Settings 在 Module SDK 中选择所安装的java版本后&#xff0c;点击右下角 Apply 3、再运行试试吧&#xff0c;成功&#xff01;

蓝桥杯(4):python动态规划DF[1]

动态规划相当于正着想&#xff1f;dfs主要适用于位置的变化&#xff1f; 子问题&#xff01;状态&#xff0c;状态转移方程 1 一维DP 1.1 定义 重叠子问题&#xff01;转换成子问题 &#xff0c;与记忆化搜索很像 1.2 例子 1.2.1 上楼梯 子问题到最终的问题只能跨一步&…

用顺序表实现通讯录

前言 这次的通讯录是基于上一篇的动态顺序表的基础上实现的&#xff0c;如果对动态顺序表不熟悉&#xff0c;可以打开这个链接阅读http://t.csdnimg.cn/9zJ5g&#xff0c;这里我们会调用动态顺序表的函数。 如果想看静态顺序表实现通讯录&#xff0c;可以打开这个链接阅读http:…