Java---Cloneable接口---浅克隆和深克隆

在Java中,我们如何实现一个对象的克隆呢?

在Java中实现对象的克隆,我们要用到Cloneable接口克隆也分为浅克隆和深克隆

1.实现浅克隆

1.重写clone方法

d7029197d72b4326a24eb326f8ff93d4.png

当我们想直接通过前面已经建立好的对象来调用Object类中的clone方法时,发现不行。因为Object类中的clone方法是被protected修饰的,只能在子类的内部调用。如下图

52f74750b2834c678556bf5425424031.png

所以我们要在Student类中重写Object类中的clone方法。 

 在Student类中重写了clone方法如下图所示

cc43cf3b6c3c4a758d16b445eea5bce3.png

重写之后,我们发现就能调用clone方法了。 

0e980672cdba4705a3427542dec92543.png

 

调用之后还会报错。

7c735760428c46a0a44c838c8ea8e978.png

 原因如下图

a4bf5a87cf764f66a2c25f26b54a796e.png

838c1819b1944936b5327213faeb054d.png

 

我们发现clone方法的返回值类型为Object类型,所以我们要进行强制类型转换。

d8fb0e29f78449c08a07c868bd8a1827.png

 

我们发现还会报出以下错 

b128956288d84cb691a05dcf6c7d2a2b.png

 解决方法

在main函数后加下图红色方框里面的字段。

b2f3b5ad4a65486eb92416387c74ff8c.png

到这一步浅克隆就完成了。

1.完整代码

class Student implements Cloneable{
    public String name;
    public int age;
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Student student=new Student("张三",18);
        Student student1=(Student) student.clone();
        System.out.println(student);
        System.out.println(student1);
    }
}

运行代码

9331d21ff37a4861a68f421013d077e4.png

发现克隆成功了。

2.浅克隆堆栈图

b355d1dd62614391b1daddfa66568d9d.png

2.实现深克隆

先来看以下代码

class Money{
    double money=24;
}
class Student implements Cloneable{
    public String name;
    public int age;
    Money m=new Money();
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", money=" + m.money +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Student student=new Student("张三",18);
        Student student1=(Student) student.clone();
        System.out.println(student);
        System.out.println(student1);
        student1.m.money=8;
    }
}

money一开始的值是24,但是我们将student1的money的值改变为8时,student的money的值也会变为24,因为上面代码只实现了浅克隆,没有实现深克隆。

上面的堆栈图如下

9ab29fb06c334a4286679084780b3924.png

由于m的值都是克隆过来的,所以两个引用都指向一个money,修改了一个money的值,自然会影响两个的m指向的值。

想解决这个问题,我们直接克隆一份money就行了。如下面的堆栈图所示。

81a0140356874b09acf3919ba7aae961.png

代码实现

class Money implements Cloneable{
    double money=24;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
class Student implements Cloneable{
    public String name;
    public int age;
    Money m=new Money();
    public Student(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", money=" + m.money +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student tmp=(Student)super.clone();//克隆了Student里面的值
        tmp.m= (Money) this.m.clone();//克隆money
        return tmp;
    }
}
public class Test {
    public static void main(String[] args)throws CloneNotSupportedException {
        Student student=new Student("张三",18);
        Student student1=(Student) student.clone();
        System.out.println(student);
        System.out.println(student1);
        student1.m.money=8;
        System.out.println("修改student1的money的值后");
        System.out.println(student);
        System.out.println(student1);
    }
}

运行代码

b424d494f4974dee894e235505439e92.png

到这里深克隆就实现了。

3.总结

浅克隆克隆的是值,深克隆克隆的是引用。 

 

 

 

 

 

 

 

 

 

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

摸鱼大数据——Hive表操作——分区表

1、介绍 特点: 分区表会在HDFS上产生目录。查询数据的时候使用分区字段筛选数据,可以避免全表扫描,从而提升查询效率 注意: 如果是分区表,在查询数据的时候,如果没有使用分区字段,它回去进行全表扫描,会降低…

positivessl泛域名证书500元13个月

随着创建网站的门槛变低,不论是个人用户还是企事业单位用户创建的域名网站也越来越多,怎么维护网络环境的安全成为了各个用户需要解决的问题。为了保护网站的数据安全,防止恶意攻击和数据泄露,大多数用户选择为域名网站安装数字证…

Laravel 图片添加水印

和这个配合使用 Laravel ThinkPhP 海报生成_laravel 制作海报-CSDN博客 代码 //水印 $x_length $imageInfo[0]; $y_length $imageInfo[1];$color imagecolorallocatealpha($posterImage, 255, 255, 255, 70); // 增加透明度参数alpha$font_size 40; //字体大小 $angle …

YOLOv10涨点改进:如何魔改注意力进行二次创新,高效替换PSA | NEU-DET为案列进行展开

💡💡💡本文改进:替换YOLOv10中的PSA进行二次创新,1)EMA替换 PSA中的多头自注意力模块MHSA注意力;2) EMA直接替换 PSA; 在NEU-DET案列进行可行性验证,1&#x…

WebGIS 智慧城市三维可视化综合管控

智慧城市可视化建设不仅提升了城市管理的科技含量和效率,还促进了城市可持续发展,提升了居民的生活质量。随着技术的不断发展和应用,智慧城市可视化建设将会更加丰富和完善,为城市发展带来更加广阔的前景。 图扑应用自研 HT for W…

Linux一键安装Docker、kkfileviewer

Linux一键安装Docker、kkfileviewer 一、安装docker 安装docker脚本 vi initDocker.sh脚本内容 #安装前先更新yum,防止连接镜像失败 yum -y update#卸载系统之前的docker(可选择,我这里直接注释了) #yum remove docker docker…

mybatis新增到数据库后返回当前ID

描述 在开发中,插入一条数据并返回当前的ID的场景很多 之前用mybatisPlus自带的api非常简单,调用完save or insert之后再getId即可。 今天使用mybatis的时候也遇到了这个场景,在此记录一下。 解决问题 直接再insert标签里面表明属性 核心…

数据挖掘与机器学习——回归分析

目录 回归分析定义: 案例: 线性回归 预备知识: 定义: 一元线性回归: 如何找出最佳的一元线性回归模型: 案例: python实现: 多元线性回归 案例: 线性回归的优缺…

抖店重磅新规!保证金下调,一张营业执照能开多个店铺了!

哈喽~我是月月 抖音平台为助力小商家实现开店低成本,轻负担,高收益的模式 在5月30日正式实施了两个政策:保证金下调,一证多开 政策一:保证金下调 这次政策,涉及的类目优惠包含了,平台近70%的…

假暴力,cf1168B. Good Triple

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 Problem - 1168B - Codeforces 二、解题报告 1、思路分析 一眼没思路&#xff0c;打个暴力试试 因为如果 s[l, r] 是一个好字符串&#xff0c;那么s[i, r]一定也是好字符串&#xff0c;其中i < l 那么…

【Mongo】索引结构

结论 Mongo3.2版本开始&#xff0c;索引的结构默认是B树。 起因 面试的时候&#xff0c;面试官问为什么Mongo DB底层使用B树而不是B树&#xff1f; 面试完赶紧恶补&#xff0c;结果发现面试官好像给我埋了个坑。。。 MongoDB官方描述&#xff1a; 翻译一下就是&#xff1…

Java 类加载机制解密一探到底

类加载是 Java 程序在运行期执行之前的重要环节&#xff0c;它决定着程序的运行效率和稳定性。本文将为您深入剖析 Java 类加载机制的整个生命周期&#xff0c;揭开神秘面纱&#xff0c;让您彻底掌握这一核心知识点。 一、类的生命周期概述 类的生命周期在Java中指的是从类被加…

【全开源】CMS内容管理系统源码(ThinkPHP+FastAdmin)

基于ThinkPHPFastAdmin的CMS内容管理系统&#xff0c;自定义内容模型、自定义单页、自定义表单、专题、统计报表、会员发布等 提供全部前后台无加密源代码和数据库私有化部署&#xff0c;UniAPP版本提供全部无加密UniAPP源码。 ​构建高效内容管理的基石 一、引言&#xff1a…

数据结构—队列(C语言实现)

文章目录 前言一、队列的概念二、队列的实现Queue.hQueue.c 三、设计循环队列问题数组实现链表实现 总结 前言 嗨喽喽&#xff01;&#xff01;小伙伴们&#xff0c;大家好哇&#xff0c;欢迎来到我的博客&#xff01; 今天将要分享的是另一种数据结构—队列&#xff0c;以及…

迈向F5G-A,开启全光万兆新时代——南通移动完成全市首个50G-PON技术验证

近日&#xff0c;南通移动在崇川区完成全市首个50G-PON万兆技术现网验证&#xff0c;标志着南通成为首批具备F5G-A(The 5th GenerationFixed Network-advanced)的万兆光网城市&#xff0c;使其成为网速最快、覆盖最全、时延最低的城市之一。 作为全光万兆的关键技术&#xff0c…

计算机图形学入门01:概述

1.什么是图形学? The use of computers to synthesize and manipulate visual information. 图形学是合成和操纵视觉信息的计算机应用。 百度百科&#xff1a;计算机图形学(Computer Graphics&#xff0c;简称CG)是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格…

深入解析MySQL 8中的角色与用户管理

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 &#x1f38f;&#xff1a;你只管努力&#xff0c;剩下的交给时间 &#x1f3e0; &#xff1a;小破站 深入解析MySQL 8中的角色与用户管理 前言角色和用户的基础概念用户&#xff08;User&#xff09;…

一个基于预训练的DenseNet121模型的人脸年龄分类系统

这篇文章采用预训练的DenseNet121模型并使用自定义的数据集类和自定义的类似正态分布的标签平滑策略来训练了一个人脸年龄分类模型&#xff0c;最后基于这个模型用tk实现了一个娱乐向的小系统。 数据集展示&#xff1a; 两个文件夹&#xff0c;分别是训练集和测试集&#xff0…

光伏组件积灰检测系统

光伏组件积灰检测系统是一种专门用于监测光伏组件表面灰尘积累情况的设备。以下是关于该系统的详细信息和特点&#xff1a; 系统概述 光伏组件积灰检测系统安装在光伏板的框架上&#xff0c;通过实时监测光伏组件表面的灰尘厚度、分布情况和清洁度&#xff0c;为运维人员提供…