zoukankan      html  css  js  c++  java
  • Java中的深克隆和浅克隆

    为什么要克隆

    首先思考一个问题, 为什么需要克隆对象? 直接new一个对象不行吗?

    克隆的对象可能包含一些已经修改过的属性, 而new出来的对象的属性都还是初始化时候的值, 所以当需要一个新的对象来保存当前对象的"状态"时就要靠克隆了.

    当然, 把对象的属性一个一个的赋值给新new的对象也是可以的, 但是这样一来麻烦不说, 二来, 我们通过源码查看 Object的clone方法是一个native方法(native方法是非Java语言实现的代码, 供Java程序调用, 要想访问比较底层的与操作系统相关的就没办法了, 只能由靠近操作系统的语言来实现), 就是快啊, 实在更底层实现的.

    我们常见的 Object a = new Object(); Object b; b = a; 这种形式的代码复制的是引用, 即对象在内存中的地址, a和b指向了同一个对象. 而通过clone方法赋值的对象跟原来的对象是同时独立存在的.

    概念

    浅克隆:

    被克隆的对象里的所有变量值都与原来的对象相同, 而所有对其他对象的引用仍然指向原来的对象. 简单说, 浅克隆仅克隆当前对象, 而不克隆当前对象所引用的对象.

    深克隆:

    被克隆的对象里的所有变量值都与原来的对象相同, 那些引用其他对象的变量将指向被复制过的新对象, 而不再是原来被引用的对象. 简单说, 深克隆不仅克隆了当前对象, 还把当前对象所引用的对象都复制了一遍.

    Object中的clone

    Object类中的clone()方法属于浅克隆. 它的工作原理如下: 在内存中先开辟一块和原始对象相同的空间, 然后复制原始对象的内容. 对于基本数据类型, 这样操作当然没问题, 但对于引用类型, 由于保存的仅仅是对象的引用, 克隆过去的引用所指向的是同一个对象.

    Java中实现浅克隆

    java中实现clone要实现 Cloneable 接口, 该接口十分简单, 源码如下:

    Java中的深克隆和浅克隆

     

    仅仅起到一个标识的作用.

    下面是一个实现浅克隆的例子:

    Java中的深克隆和浅克隆

     

    可以看到, 对象确实不是原来的对象了, 但是其中的引用对象却还是原来的对象.

    浅克隆对于引用对象仅拷贝引用.

    如果一个对象只包含原始数据或者不可变对象域(如: String), 推荐使用浅克隆.

    Java中实现深克隆

    将类中的所有引用类型都进行clone, 并重写对象clone()方法, 对所有引用类型进行clone.

    代码如下:

    Java中的深克隆和浅克隆

     

    将所有引用类型都进行clone, 实现了深克隆.

    Java序列化克隆

    如果引用类型中海包括引用类型, 要实现多层克隆会很麻烦, 这使用可以使用序列化和反序列化的方式实现对象的深克隆.

    把对象写到字节流中的过程是序列化的过程, 而把对象从字节流中读出来的过程是反序列化的过程. 由于Java序列化的过程中, 写在流中的是对象的一个拷贝, 而原对象仍然在JVM中, 所以可以利用这个原理来实现对对象的深克隆.

    上面代码使用序列化实现如下:

    Java中的深克隆和浅克隆

     

    可以将序列化克隆封装为一个方法, 如下所示:

    Java中的深克隆和浅克隆

     

    通过该工具类即可进行深度克隆. 要是用该方法, 对象、对象的所有引用类型、引用类型中的引用类型都要实现 Serializable 接口.


    当然, 对象中的final对象是不能进行clone的, 因为final的限制.

    如果用线程安全的类实现Cloneable, 要保证它的clone方法做好同步工作, 默认的Object.clone方法是没有同步的.

  • 相关阅读:
    cmanformat
    mysql-sql语言参考
    jQuery 判断多个 input checkbox 中至少有一个勾选
    Java实现 蓝桥杯 算法提高 计算行列式
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
  • 原文地址:https://www.cnblogs.com/hujingnb/p/10181582.html
Copyright © 2011-2022 走看看