当前位置: 首页 > news >正文

浅克隆与深克隆

1、浅克隆

1.1、什么是浅克隆?

        被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然

        指向原来的对象(克隆对象与原型对象共享引用数据类型变量)。

        如下图所示:

                

1.2、浅克隆代码实现

         类实现接口 Cloneable,表示该类的对象是可以克隆的

         示例代码1:

public class ConcretePrototype implements Cloneable {public ConcretePrototype() {System.out.println("具体的对象创建完成!");}@Overrideprotected ConcretePrototype clone() throws CloneNotSupportedException {System.out.println("具体的对象复制成功!");return (ConcretePrototype)super.clone();}
}

      测试

@Testpublic void test01() throws CloneNotSupportedException {ConcretePrototype c1 = new ConcretePrototype();ConcretePrototype c2 = c1.clone();System.out.println("对象c1和c2是同一个对象?" + (c1 == c2));}

      打印结果:

             对象c1和c2是同一个对象?true

      示例代码2:

            在 类 ConcretePrototype 中添加一个引用类型的属性Person,如下所示:

public class ConcretePrototype implements Cloneable {private Person person;public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}void show(){System.out.println("嫌疑人姓名: " +person.getName());}public ConcretePrototype() {System.out.println("具体的对象创建完成!");}@Overrideprotected ConcretePrototype clone() throws CloneNotSupportedException {System.out.println("具体的对象复制成功!");return (ConcretePrototype)super.clone();}}public class Person {private String name;public Person() {}public Person(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
}

      测试:

@Testpublic void test02() throws CloneNotSupportedException {ConcretePrototype c1 = new ConcretePrototype();Person p1 = new Person();c1.setPerson(p1);//复制c1ConcretePrototype c2 = c1.clone();//获取复制对象c2中的Person对象Person p2 = c2.getPerson();p2.setName("慕容复");//判断p1与p2是否是同一对象System.out.println("p1和p2是同一个对象?" + (p1 == p2));c1.show();c2.show();}

     打印结果:

            p1和p2是同一个对象?true
            嫌疑人姓名:慕容复
            嫌疑人姓名:慕容复

     p1与p2是同一对象,这是浅克隆的效果,也就是对具体原型类中的引用数据类型的属性进行

     引用的复制

2、深克隆

2.1、什么是深克隆

         除去那些引用其他对象的变量,被复制对象的所有变量都含有与原来的对象相同的值。那些

         引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言

          之,深复制把要复制的对象所引用的对象都复制了一遍。如下图所示:

                

2.2、深克隆代码实现

         对于上边浅克隆示例2中的代码,如果有需求场景中不允许共享同一对象,那么就需要使用

         “深拷贝”,如果想要进行深拷贝需要使用到对象序列化流 (对象序列化之后,再进行反序列化

          获取到的是不同对象)。代码如下

@Testpublic void test03() throws Exception {ConcretePrototype c1 = new ConcretePrototype();Person p1 = new Person("峰哥");c1.setPerson(p1);//创建对象序列化输出流ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("c.txt"));//将c1对象写到文件中oos.writeObject(c1);oos.close();//创建对象序列化输入流ObjectInputStream ois = new ObjectInputStream(new FileInputStream("c.txt"));//读取对象ConcretePrototype c2 = (ConcretePrototype) ois.readObject();Person p2 = c2.getPerson();p2.setName("凡哥");//判断p1与p2是否是同一个对象System.out.println("p1和p2是同一个对象?" + (p1 == p2));c1.show();c2.show();}

3、总结

     1)Java中的Object类中提供了 `clone()` 方法来实现“浅克隆”。需要注意的是要想实现克隆

           的Java类必须实现一个标识接口 Cloneable ,来表示这个Java类支持被复制。

     2)其实现在不推荐大家用Cloneable接口,实现比较麻烦,现在借助Apache Commons或

          者springframework可以直接实现:
              (1)浅克隆:BeanUtils.cloneBean(Object obj);

                                      BeanUtils.copyProperties(S,T);
              (2)深克隆:SerializationUtils.clone(T object);
          BeanUtils是利用反射原理获得所有类可见的属性和方法,然后复制到target类。
          SerializationUtils.clone()就是使用我们的前面讲的序列化实现深克隆,当然你要把要克隆

          的类实现Serialization接口。


http://www.mrgr.cn/news/36160.html

相关文章:

  • 【测试项目】——个人博客系统自动化测试
  • 脏读查询SQL SELECT查询配置(DM8:达梦数据库)
  • 第L2周:机器学习|线性回归模型 LinearRegression:1. 简单线性回归模型
  • QT创建线程,QT多线程的创建和使用,QT线程池
  • Kolmogorov-Arnold——代替 MLP以提高模型的代表性和性能
  • 替换jar包中class文件
  • 去年营收增速仅1.4%,成长性恐不足,这家批发业公司终止了
  • 代码随想录冲冲冲 Day55 图论Part7
  • 节点分类、链路预测和社区检测的评价指标
  • 【C++ Primer Plus习题】17.7
  • DBAPI如何实现插入数据前先判断数据是否存在,存在就更新,不存在就插入
  • 机器学习算法与Python实战 | 三万字详解!GPT-5:你需要知道的一切(上)建议收藏!
  • OpenCV4.8 开发实战系列专栏之 01- 环境搭建与图像读写
  • 使用 from __future__ import annotations 语句来允许在类型注释中使用尚未定义的类名
  • centos7安装Redis单机版
  • AI时代下的程序员:如何应对技术变革与提升竞争力
  • 先进封装技术 Part01---“凸块”(Bump)科普
  • 小孩真的需要手机上学吗?怎样远程了解他在学校用iPhone干什么?
  • 工作安排 - 华为OD统一考试(E卷)
  • Educational Codeforces Round 20 F. Coprime Subsequences(DP+容斥)