Java:Clonable 接口和拷贝

news2024/11/14 17:23:23

一 Clonable 接口

在 Java SE 中,Cloneable 是一个标记接口(Marker Interface),它位于 java.lang 包中。这个接口的主要目的是标识实现该接口的类能够被合法地克隆(即可以调用 Object 类中的 clone() 方法)。

1.当我们点入Clonable 接口的源代码中,可以发现里面什么都没有。

因为Cloneable 是一个标记接口,用来表明类的对象可以被克隆。 

2.如果不实现 Cloneable 接口而直接调用 clone() 方法,系统将抛CloneNotSupportedException 异常。 

 

3.Clonable 接口的实现

第一步

class Money{
    public double money=9.9;
}
public class Person {
    public String name;
    public int age;
    public Money m=new Money();

    public Person(String name,int age){
        this.name=name;
        this.age=age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", m=" + m +
                '}';
    }
}
public class Test {
    public static void main(String[] args) {
        Person person1=new Person("wang",10);
        Person person2=person1.
    }

}

问题:但是我们发现 ,在person1的引用中没有发现clone() 

第二步

实现Cloneable接口,并重写Object接口的克隆方法

class Money{
     public double money=9.9;

}
public class Person implements Comparable{
    public String name;
    public int age;
    public Money m=new Money();

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) {
        Person person1=new Person("wang",10);
        Person person2=person1.clone();
    }

}

问题:但我们发现,代码依旧报错。

第三步

由于clone()方法返回值是Object是父类,所以要将克隆方法强转为子类。

class Money{
    public double money=9.9;
}
public class Person implements Comparable{
    public String name;
    public int age;
    public Money m=new Money();

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) {
        Person person1=new Person("wang",10);
        Person person2=(Person) person1.clone();
    }

}

 

问题:但是代码依旧报错

第四步

因为有异常,所以得先处理 

 

class Money{
    public double money=9.9;
}
public class Person implements Comparable{
    public String name;
    public int age;
    public Money m=new Money();

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

    @Override
    protected Object clone()
            throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args) 
            throws CloneNotSupportedException{
        Person person1=new Person("wang",10);
        Person person2=(Person) person1.clone();
    }

}

 

最终运行成功 

过程如下

 二 拷贝

1.浅拷贝

class Money{
    public double money=9.9;
}
public class Person implements Cloneable{
    public String name;
    public int age;
    public Money m=new Money();

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

    @Override
    protected Object clone()
            throws CloneNotSupportedException {
        return super.clone();
    }
}
public class Test {
    public static void main(String[] args)
            throws CloneNotSupportedException{
        Person person1=new Person("wang",10);
        Person person2=(Person) person1.clone();
/*        System.out.println(person1);
        System.out.println(person2);*/
        System.out.println("修改前"+person1.m.money);
        System.out.println("修改前"+person2.m.money);
        person1.m.money=100;
        System.out.println("修改后"+person1.m.money);
        System.out.println("修改后"+person2.m.money);
    }

}

 

我们可以看出,只克隆了Person对象,没有克隆Money对象 ,这种现象就叫做浅拷贝。

2.深拷贝

如何让Money也进行克隆呢?

接下来就是深拷贝过程

class Money implements Cloneable{
    public double money=9.9;

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

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

    @Override
    protected Object clone()
            throws CloneNotSupportedException {
        //return super.clone();
        Person tem=(Person) super.clone();
        tem.m=(Money) this.m.clone();
        return tem;
    }
}
public class Test {
    public static void main(String[] args)
            throws CloneNotSupportedException{
        Person person1=new Person("wang",10);
        Person person2=(Person) person1.clone();
/*        System.out.println(person1);
        System.out.println(person2);*/
        System.out.println("修改前"+person1.m.money);
        System.out.println("修改前"+person2.m.money);
        person2.m.money=100;
        System.out.println("修改后"+person1.m.money);
        System.out.println("修改后"+person2.m.money);
    }

}

 

过程如下:

 

注:clone() 默认执行浅拷贝,若需要深拷贝,需要手动处理。 

希望能对大家有所帮助!!! 

 

 

 

 

 

 

 

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

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

相关文章

Electron应用程序打包后运行报错cannot find module ‘@vue/cli-service‘

本项目打包运行后报错问题的解决办法,类似于其他cannot find module XXX’的报错,也基本可以解决 文章目录 electron应用程序打包后运行报错排查问题解决办法 electron应用程序打包后运行报错 错误如下: 提示找不到该模块 排查问题 本项…

互联网广告产品基础知识

一 计价与效果 广告产品如何估算收入? 一种是从需求侧计算:按照广告主数量进行拟合;一种是从供给侧计算:按照曝光量和千次曝光单价进行拟合。 需求侧 从需求侧,也就是广告主侧,来计算广告产品的总收入&…

Linux命令:用于创建新的用户组的命令行工具groupadd 详解

目录 一、概述 二、组标识符GID 1、定义 (1)标识符 (2)与UID的关系 2、GID的作用 (1)用户组管理 (2)文件权限控制 (3)用户权限管理 (4&…

threejs性能优化之gltf文件压缩threejs性能优化之glb文件压缩

在使用Three.js进行3D图形开发时,GLTF(GL Transmission Format)文件因其高效性和灵活性而广受欢迎。然而,随着模型复杂度的增加,GLTF文件的大小也会显著增加,这可能会对加载时间和渲染性能产生负面影响。为…

插入与冒泡排序(C++)

\一、插入排序 1 简介 插入排序,也称为直接插入排序,其排序思想和我们平时打扑克牌时排序类似。 2 算法步骤 将第一个元素看作已排序序列,第二个到最后一个看作未排序序列。 第二个元素,与之前已排序号的序列进行对比&#x…

【我的 PWN 学习手札】tcache stash with fastbin double free —— tcache key 绕过

参考看雪课程:PWN 探索篇 前言 tcache key 的引入使得 tcache dup 利用出现了困难。除了简单利用 UAF 覆写 key 或者House Of Karui 之外,还可以利用 ptmalloc 中的其他机制进行绕过。 一、Tcache Stash with Fastbin Double Free 之前是 double free …

软考中级软件设计师——知识产权学习记录

软考中级软件设计师——知识产权 著作权人身权著作财产权著作权侵权行为 计算机软件著作权基本知识计算机软件著作权侵权 专利地域性与专利权申请基本知识专利权侵权 职务作品委托开发商业秘密权基本知识商业秘密侵权 商标权与商标注册基本知识商标权侵权 著作权 著作权也称为…

Spring的任务调度

Spring的任务调度 1.概述 Spring框架为任务调度提供了专门的解决方案。在Spring框架的org.springframework.scheduling包中,通过对JDK 的ScheduledExecutorService接口的实例进行封装,对外提供了一些注解和接口,为开发者处理定时任务提供了…

网安面试会问到的:http的长连接和短连接

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

探索 Python 的火焰:Fire 库的神秘力量

文章目录 🔥 探索 Python 的火焰:Fire 库的神秘力量第一部分:背景介绍第二部分:Fire 库是什么?第三部分:如何安装 Fire?第四部分:简单库函数使用方法第五部分:场景应用第…

32.递归、搜索、回溯之floodfill算法

0.简介 1.图像渲染 . - 力扣(LeetCode) 题目解析 算法原理 代码 class Solution {int[] dx { 0, 0, 1, -1 };int[] dy { 1, -1, 0, 0 };int m, n;int prev;public int[][] floodFill(int[][] image, int sr, int sc, int color) {if (image[sr][sc]…

yolov5足球运动分析-速度分析-足球跟踪

足球分析项目 引言 在现代体育分析领域,利用先进的计算机视觉技术和机器学习模型对比赛视频进行深入解析已成为一种趋势。本项目旨在通过YOLO(You Only Look Once)这一顶级的人工智能目标检测模型来识别并跟踪足球比赛中的球员、裁判以及足球…

【每日一题】LeetCode 2374.边积分最高节点(图、哈希表)

【每日一题】LeetCode 2374.边积分最高节点(图、哈希表) 题目描述 给定一个有向图,图中包含 n 个节点,节点编号从 0 到 n - 1。每个节点都有一个出边,指向图中的另一个节点。图由一个长度为 n 的整数数组 edges 表示…

江协科技STM32学习- P15 TIM输出比较

🚀write in front🚀 🔎大家好,我是黄桃罐头,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝​…

6张图掌握提示词工程师工作范围与工作技巧(提示词原理篇)

在人工智能的疆域中,提示词工程师扮演着至关重要的角色。他们精心设计的话语,是引导AI模型理解人类需求、激发创造力的关键。如同指挥官的号令,提示词工程师的每一个提问,都让AI的潜力得到释放,让技术与智慧的对话更加…

如何有效检测住宅IP真伪?

在当今的互联网时代,住宅IP(即家庭用户通过宽带服务提供商获得的IP地址)在跨境电商、广告投放、网络安全等多个领域扮演着重要角色。然而,随着网络环境的复杂化和欺诈行为的增多,如何有效检测和辨别住宅IP的真伪成为了…

2024年csp-j 初赛 真题+答案解析

恭喜CSP-J组考生完成第一轮认证! 今天是CSP-J/S初赛的考试日,首先要祝贺所有参加CSP-J组考试的同学顺利完成第一轮认证!

C++中的new与delete

目录 1.简介 2.底层 1.简介 new是升级版的malloc,它会先开空间再去调用构造函数。 delete是升级版的free,它会先调用析构函数再free掉空间。 class A { public:A(int a10, int b10){a a1;b b1;}private:int a;int b; };int main() {//new会先开空间…

大数据Flink(一百二十三):五分钟上手Flink MySQL连接器

文章目录 五分钟上手Flink MySQL连接器 一、创建数据库表 二、​​​​​​创建session集群 三、源表查询 四、​​​​​窗口计算 五、​​​​​​结果数据写回数据库 五分钟上手Flink MySQL连接器 MySQL Connector可以将本地或远程的MySQL数据库连接到Flink中&#x…

以太网接口MII 和 RMII

媒体独立接口 (MII) 是连接以太网MAC (媒体访问控制) 设备和PHY (物理层) 设备的标准化方法。其主要目的是促进以太网系统这两个基本组件之间的通信。 媒体独立接口 (MII) 介质独立接口 (MII) 是由 IEEE 802.3 标准定义的并行接口。MII 的管理接口允许配置和控制多个 PHY 设备…