前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java中的深克隆和浅克隆

Java中的深克隆和浅克隆

作者头像
烟草的香味
发布2019-07-25 10:58:34
1.7K0
发布2019-07-25 10:58:34
举报
文章被收录于专栏:烟草的香味烟草的香味

为什么要克隆

首先思考一个问题, 为什么需要克隆对象? 直接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 接口, 该接口十分简单, 源码如下:

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

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

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

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

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

Java中实现深克隆

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

代码如下:

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

Java序列化克隆

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

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

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

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

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


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

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-01-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 烟草的香味 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么要克隆
  • 概念
  • Object中的clone
  • Java中实现浅克隆
  • Java中实现深克隆
  • Java序列化克隆
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档