• 什么是深克隆,浅克隆?(案例详解)


    【辰兮要努力】:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行!

    博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端、后台、数据库、项目案例等相关知识点总结,感谢你的阅读和关注,希望我的博客能帮助到更多的人,分享获取新知,大家一起进步!

    吾等采石之人,应怀大教堂之心,愿我们奔赴在各自的热爱里…

    一、基础概念

    原型模式的克隆分为浅克隆和深克隆

    浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。

    在这里插入图片描述
    深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

    在这里插入图片描述


    二、案例学习

    先定义一个学生类

    public class Student {
    
        //学生的姓名
        private String name;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    定义一个成绩单类集成学生类

    public class Citation implements Cloneable {
    
        private Student stu;
    
        public Student getStu() {
            return stu;
        }
    
        public void setStu(Student stu) {
            this.stu = stu;
        }
    
        @Override
        public Citation clone() throws CloneNotSupportedException {
            return (Citation) super.clone();
        }
    
        public void show() {
            System.out.println(stu.getName() + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    客户端测试类

    public class CitaionTest {
        public static void main(String[] args) throws CloneNotSupportedException {
            //1,创建原型对象
            Citation citation = new Citation();
            //创建张三学生对象
            Student stu = new Student();
            stu.setName("张三");
            citation.setStu(stu);
    
            citation.show();
            System.out.println("===原型模式克隆后===");
    
            //2,克隆奖状对象
            Citation citation1 = citation.clone();
            Student stu1 = citation1.getStu();
            stu1.setName("李四");
    
            //3,调用show方法展示
            citation.show();
            citation1.show();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    张三同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
    ===原型模式克隆后===
    李四同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
    李四同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
    
    Process finished with exit code 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    分析:因为复制后对象引用原对象的【引用对象】,所有修改对应值后原对象对应值会修改;


    深克隆的案例

    序列化(Serialization)就是将对象写到流的过程,写到流中的对象是原有的对象的一个拷贝,而原对象仍存在内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且也可以复制其引用的成员对象,因此通过序列化将对象写入一个流中,再从流中将其读出来,从而实现深克隆。

    public class CitaionTest {
        public static void main(String[] args) throws Exception {
            //1,创建原型对象
            Citation citation = new Citation();
            //创建张三学生对象
            Student stu = new Student();
            stu.setName("张三");
            citation.setStu(stu);
    
            //创建对象输出流对象
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/file/a.txt"));
            //写对象
            oos.writeObject(citation);
            //释放资源
            oos.close();
    
            //创建对象输入流对象
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/file/a.txt"));
            //读取对象
            Citation citation1 = (Citation) ois.readObject();
            //释放资源
            ois.close();
            Student stu1 = citation1.getStu();
            stu1.setName("李四");
    
            citation.show();
            citation1.show();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    控制台输出

    张三同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
    李四同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状
    
    • 1
    • 2

    注意事项:由于是通过字节流序列化实现的深克隆,因此每个对象必须能被序列化,必须实现 Serializable 接口,标识自己可以被序列化,否则会抛出异常 (java.io.NotSerializableException)

    在这里插入图片描述

    • 序列化:把对象写到流里
    • 反序列化:把对象从流中读出来

    📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤️ 分享👥 留言💬thanks!!!

    📚愿我们奔赴在各自的热爱里!

  • 相关阅读:
    gitHub添加ssh
    扩散模型实战(十):Stable Diffusion文本条件生成图像大模型
    2022年ArchSummit全球架构师峰会杭州站感想
    springboot系列(十七):集成在线接口文档Swagger2|超级详细,建议收藏
    MFC Windows 程序设计[329]之多彩下拉组合编辑框实例(附源码)
    Java switch case 条件语句用法大全
    window事件-滚动事件(点击回顶部效果)
    TCP的三次握手与四次挥手
    火车票识别易语言代码
    Apache ShenYu网关初体验
  • 原文地址:https://blog.csdn.net/weixin_45393094/article/details/125817131