zoukankan      html  css  js  c++  java
  • JAVA对象的浅克隆和深克隆

    浅克隆

    • 对于基本数据类型的属性,复制一份给新的对象。
    • 对于非基本数据类型的属性(对象),复制一份对象的引用给新的对象。
      (即,新对象和旧对象中的非基本数据类型的属性的“指针” 指向同一个对象)

    浅克隆步骤

    1. 实现java.lang.Cloneable接口
    2. 重写java.lang.Object.clone方法

    代码

    class Test{
        
    }
    
    class Father implements Cloneable {
        int i=5;
        Test test = new Test();
    
        public void setI(int i) {
            this.i = i;
        }
    
        @Override
        protected Object clone() {
            try{
                return super.clone();
            }catch (CloneNotSupportedException e){
                return null;
            }
        }
    
        public static void main(String[] args) {
            Father father = new Father();
            //修改基本数据类型
            father.setI(10);
            //执行clone方法
            Father clone =(Father) father.clone();
    
            System.out.println(clone.i);
            System.out.println(clone.test ==father.test);
            System.out.println(father==clone);
    
        }
    }
    

    运行结果

    10
    true
    false
    
    Process finished with exit code 0
    

    深克隆

    与浅克隆的区别是,对于非基本数据类型的属性,复制的不是原来的引用。
    (即,新对象和旧对象中的非基本数据类型的属性的“指针” 不是 指向同一个对象)

    深克隆步骤

    1. 实现java.io.Serializable
    2. 实现clone方法,将对象序列化转换为字节流,再将字节流反序列化为对象返回即可

    代码

    class Test implements  Serializable{
    
    }
    
    class Father implements Serializable {
        int i=5;
        Test test = new Test();
    
        public void setI(int i) {
            this.i = i;
        }
    
        public Father clone(){
            try {
                // 将该对象序列化成流,因为写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。所以利用这个特性可以实现对象的深拷贝    
                ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                ObjectOutputStream objout = new ObjectOutputStream(byteOut);
                objout.writeObject(this);
                //将流序列化成对象
                ByteArrayInputStream bytein = new ByteArrayInputStream(byteOut.toByteArray());
                ObjectInputStream objin = new ObjectInputStream(bytein);
                return (Father) objin.readObject();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        public static void main(String[] args) {
            Father father = new Father();
            //修改基本数据类型
            father.setI(10);
            //执行clone方法
            Father clone =(Father) father.clone();
    
            System.out.println(clone.i);
            System.out.println(clone.test ==father.test);
            System.out.println(father==clone);
    
        }
    }
    

    运行结果

    10
    false
    false
    
    Process finished with exit code 0
    

    Tip:

    实际场景中,很少使用克隆,更多的是对象属性之间的克隆。
    一般使用BeanUtils工具类的public static void copyProperties(Object source, Object target)方法。

  • 相关阅读:
    查看python中SQLite版本和sqlite3版本
    ubuntu系统安装与卸载
    CentOS下如何使用yum查看安装过的软件包
    【linux】CentOS7 升级sqlite3
    什么是Python的metaclass
    Python
    Python对字典分别按键(key)和值(value)进行排序
    python 用正则表达式去除特殊字符的两种方法
    从思维导图中学习javascript第五章字符串函数
    从思维导图中学习javascript第三章数组
  • 原文地址:https://www.cnblogs.com/bendandedaima/p/13532103.html
Copyright © 2011-2022 走看看