zoukankan      html  css  js  c++  java
  • 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());
        }
    
  • 相关阅读:
    BZOJ 4805: 欧拉函数求和 杜教筛
    BZOJ 2694: Lcm 莫比乌斯反演 + 积性函数 + 线性筛 + 卡常
    BZOJ 2693: jzptab 莫比乌斯反演 + 积性函数 + 筛法
    BZOJ 2154: Crash的数字表格 莫比乌斯反演
    BZOJ 3884: 上帝与集合的正确用法 扩展欧拉定理 + 快速幂
    BZOJ 3595: [Scoi2014]方伯伯的Oj Splay + 动态裂点 + 卡常
    GitHub的使用
    Selenium模块的安装
    关于__new__和__init__
    博客一键保存本地exe可视化界面文件
  • 原文地址:https://www.cnblogs.com/z5452830/p/13874634.html
Copyright © 2011-2022 走看看