• JAVA笔记整理-克隆(clone)


    、对象的克隆

    1、为什么需要克隆?

    ​ 对于基本数据类型,可以将值直接复制给另一个变量,这里两个变量相互独立,而引用数据类型(自定义类) 对于引用类型的赋值并没有产生新的个体,而是将两个变量的类型指向同一个对象。 (本质只有一个对象),如果想要赋值的对象与原始对象独立,则需要进行“对象克隆”

    2、如何克隆

    ​ 我们知道任意一个类都继承自Object类,其中Object类提供一个clone方法 用于克隆对象。

    ​ 实现步骤:

    ​ a、 实现 接口 Cloneable

    ​ b、重写 clone方法(由于该方法是Object的 protectect修饰 不能直接访问)

    3、浅克隆和深克隆

    3.1、浅克隆

    在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。

    Java的对象克隆默认是浅克隆,

    3.2、深克隆

    在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

    简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制

    实现深克隆的方式:

    ​ 1、需要将克隆对象的引用数据类型 也实现克隆

    public class Student implements  Cloneable {
        private int id;
        private String sname;
        private int age;
        //收货地址
        private Address address;
        //实现深克隆
          @Override
        protected Object clone() throws CloneNotSupportedException {
    //        return super.clone();
             Student stu = (Student)super.clone();
             // 获取学生的address
            Address address =  (Address) stu.getAddress().clone();
            // 将address对象放入 新克隆的stu中
            stu.setAddress(address);
            return stu;
    
        }
       }
       
       public class Address implements Cloneable{
        //联系人
        private String contectName;
        //联系电话
         private String contectPhone;
            @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
       }
    

    测试:

     public static void main(String[] args) throws CloneNotSupportedException {
             // 创建学生对象
            Student stu1 = new Student(1001,"张三",22);
            Address address = new Address("马创的女朋友","18888888888");
            // 将收货地址 与该学生对象关联
            stu1.setAddress(address);
    
            //克隆一个对象
            Student stu2 = (Student)stu1.clone();
    
            System.out.println(stu1.getId()+"---"+stu1.getSname());
            System.out.println(stu2.getId()+"---"+stu2.getSname());
           // 问题:是否会克隆新的address对象 还是说address的内存地址相同
            System.out.println(stu1.getAddress());
            System.out.println(stu2.getAddress());
    
            // 对于克隆对象的引用数据类型,它默认不会创建引用数据类型的 新对象
            //  这种方式称为“浅克隆”
    
            // Java也可以实现深克隆
            System.out.println(stu1.getAddress().getContectName());
            System.out.println(stu2.getAddress().getContectName());
        }
    
  • 相关阅读:
    Hbase安装
    Spring bean和Java Bean的区别
    PyTorch初始教程1入门教程
    GeoMesa教程索引
    Applied Spatial and Spatiotemporal Analysis(应用空间和时空分析)Applied Spatiotemporal Data Mining时空数据挖掘
    分布式存储和分布式计算
    geospark geotrellis geomesa geowave的异同
    halconsort_contours_xld xid轮廓进行排序
    平衡树:为什么Redis内部实现用跳跃表
    TypeScript里string和String,真不是仅仅是大小写的区别
  • 原文地址:https://www.cnblogs.com/z5452830/p/13874634.html
Copyright © 2020-2023  润新知