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

news2024/12/23 5:25:23

目录

  • 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;
    }
    @Override
    public 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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
    @Override
    protected 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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
    @Override
    protected 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;
    @Override
    protected 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;
    }
    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +
                '}';
    }
    @Override
    protected 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.coloradmin.cn/o/1571410.html

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

相关文章

吴恩达2022机器学习专项课程(一) 5.2 向量化(1) 5.3 向量化(2)

问题预览/关键词 什么是向量化?向量化的好处是?如何向量化多元线性回归函数的参数?如何在Python中向量化参数?计算机底层是如何计算向量化的?向量化示例 笔记 1.向量化 一种在数学和计算中广泛使用的概念&#xff…

vscode 连接远程服务器 服务器无法上网 离线配置

离线配置 vscode 连接远程服务器 .vscode-server 1. .vscode-server下载 使用vscode连接远程服务器时会自动下载配置.vscode-server文件夹,如果远程服务器无法联网,则需要手动下载 1)网址:https://update.code.visualstudio.com…

冒泡排序解读

在信息爆炸的时代,数据无处不在,而如何有效地管理和处理这些数据,成为了现代计算机科学的一个重要课题。排序算法,作为数据处理的基本工具之一,对于数据的组织、搜索和分析起着至关重要的作用。今天,我们就…

ABBYY FineReader15免费电脑OCR图片文字识别软件

产品介绍:ABBYY FineReader 15 OCR图片文字识别软件 ABBYY FineReader 15是一款光学字符识别(OCR)软件,专门设计用于将扫描的文档、图像和照片中的文本转换成可编辑和可搜索的格式。这款软件利用先进的OCR技术,能够识别…

Word·VBA文档合并

目录 1,复制法,不保留原文档格式2,复制法,保留原文档格式3,插入法,保留原文档格式 之前的文章《WordVBA实现邮件合并》虽然可以生成邮件合并文档结果,但是不能像《python实现word邮件合并》一样…

虚幻UE5智慧城市全流程开发教学

一、背景 这几年,智慧城市/智慧交通/智慧水利等飞速发展,骑士特意为大家做了一个这块的学习路线。 二、这是学习大纲 1.给虚幻UE5初学者准备的智慧城市/数字孪生蓝图开发教程 https://www.bilibili.com/video/BV1894y1u78G 2.UE5数字孪生蓝图开发教学…

【氮化镓】缓冲层结构对GaN HEMT射频性能的影响

【Effect of different layer structures on the RF performance of GaN HEMT devices】 研究总结: 本研究探讨了不同缓冲层结构对氮化镓高电子迁移率晶体管(GaN HEMT)射频性能的影响。通过对比三种不同缓冲层结构的GaN HEMT设备&#xff0…

使用LIO-SAM进行点云赋色 与 激光雷达和相机的精细化标定(防止自己忘记的博客)----- 激光雷达和相机的精细化标定

目录 1 标定相机 2 激光雷达、相机粗标定 3 精细化标定激光雷达和相机 1 标定相机 使用Kaliber标定D435i相机,本次标定的分辨率为1920*1080,相机的内参如下: FX:1439.96402547 FY:1442.82612329 CX:979.0…

“鹰王”语出惊人!三大股指尾盘急转直下?加密市场逆势反弹,多头占据上风!

周四早盘时段,由于最新初请失业金人数增加,有助于支撑降息预期,美股走高。随后,美联储官员的鹰派表态打压了投资者信心,三大股指尾盘急转直下,从盘中高点下跌超过2%,道指盘中波动超860点。 美国…

包子凑数【蓝桥杯】/完全背包

包子凑数 完全背包 完全背包问题和01背包的区别就是,完全背包问题每一个物品能取无限次。 思路:当n个数的最大公约数不为1,即不互质时,有无限多个凑不出来的,即n个数都可以表示成kn,k为常数且不为1。当n个…

ChatGPT 与 OpenAI 的现代生成式 AI(上)

原文:Modern Generative AI with ChatGPT and OpenAI Models 译者:飞龙 协议:CC BY-NC-SA 4.0 序言 本书以介绍生成式 AI 领域开始,重点是使用机器学习算法创建新的独特数据或内容。它涵盖了生成式 AI 模型的基础知识&#xff0c…

金三银四面试题(十四):Java基础问题(5)

这部分面试题多用于面试的热身运动,对很多找实习和准备毕业找工作的小伙伴至关重要。 避免序列化 可以使用transient 关键字修饰不想进行序列化的变量。 transient 关键字的作用是:阻止实例中那些用此关键字修饰的变量序列化;当对象被反序列…

在线除背景抠图工具推荐,通过AI自动去除人物背景,给图片背景换色

发现了一个好的在线除水印的网站,这里由「易极赞」的小编来分享给大家。它就是我们今天的主角SnapEdit。 工具简介 SnapEdit 借助至极先进的人工智能技术,得以自动判别图像的主体与背景,飞速地移除背景且保留主体的细微之处和边缘轮廓&…

Trace链异常检测汇总

微服务应用与单块应用完全不同,一个微服务系统少则有几十个微服务组成,多则可能有上百个服务。比如BAT级别的互联网公司,一般都超过上百个服务,服务之间的依赖关系错综复杂,如果没有有效的监控手段,那么出现…

【Linux】Linux进程学习(基本认知)

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 前言一、冯诺依曼体系二、系统管理三、进程理解3.1 代码与数据3.2 进程控制块 四…

向量数据库 | AI时代的航道灯塔

向量数据库 | AI时代的航道灯塔 什么是向量检索服务拍照搜商品 你使用过向量数据库吗?使用体验?为什么向量数据库能借由大模型引起众多关注向量数据库在当前AI热潮中是昙花一现,还是未来AI时代的航道灯塔? 今天的话题主要是讨论向…

华清远见STM32MP157开发板助力嵌入式大赛ST赛道MPU应用方向项目开发

第七届(2024)全国大学生嵌入式芯片与系统设计竞赛(以下简称“大赛”)已经拉开帷幕,大赛的报名热潮正席卷而来。嵌入式大赛截止今年已连续举办了七届,为教育部认可的全国普通高校大学生国家级A类赛事&#x…

Linux制作C++静态库和动态库并使用示例

创建动态库&#xff1a; 编写源文件&#xff1a; // sub.h 显式调用 #include <iostream>extern "C" int sub(int a, int b);// sub.cpp #include "sub.h"int sub(int a, int b) {return a - b; }// quadrature.h 隐式调用 #include <iostream&…

云服务器centos提示 Cannot prepare internal mirrorlist: No URLs in mirrorlist的解决办法

yum update -y CentOS-8 - AppStream 118 B/s | 38 B 00:00 Error: Failed to download metadata for repo AppStream: Cannot prepare internal mirrorlist: No URLs in mirrorlist 执行下面的命令就可…

LeetCode题练习与总结:合并区间--56

一、题目描述 示例 1&#xff1a; 输入&#xff1a;intervals [[1,3],[2,6],[8,10],[15,18]] 输出&#xff1a;[[1,6],[8,10],[15,18]] 解释&#xff1a;区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].示例 2&#xff1a; 输入&#xff1a;intervals [[1,4],[4,5]] 输出&a…