java 实现克隆_Java中如何实现深克隆

实现深克隆的方法有三种:

一、重写clone方法,clone中嵌套clone

这种方法的原理其实就是在需要克隆的对象以及该对象的引用类型的变量的类中全部实现cloneable接口,否则抛出CloneNotSupportedException将引用类型的变量也克隆一份。实际的操作上就是改写源对象的clone方法,在其内部嵌套克隆方法。

首先让源对象调用克隆方法获得克隆的对象,然后获得被克隆对象的引用类型的成员变量对象,对该成员变量对象调用克隆方法,此时成员变量对象也被克隆了一份,最后将该克隆的成员变量对象,设置为克隆对象的新的成员变量,再返回该被克隆的对象,即可实现深克隆。

二、使用序列化流

其原理是:首先使要序列化的对象和该对象的引用类型成员变量对象的类都实现Serializable接口,将对象序列化到输出流中,然后再反序列化为对象就完成了完全的复制操作了,反序列化对象类似于运行新对象的构造方法。一般序列化到外部文件,此时只需要克隆对象,并不需要外部文件,因此我们的序列化和反序列化也应该在内存中进行最好,因此还使用到在内存操作数据的流ByteArrayOutputStream和ByteArrayInputStream,他们的输出和读取都默认是在内存的数组中操作。

首先创建一个ByteArrayOutputStream内存数组输出流,创建一个ObjectOutputStream序列化流,并传入内存数组输出流,使用序列化流的writeobject方法将要序列化的对象写入内部数组中,然后创建一个ByteArrayInputStream内存数组读取流,传入一个读取数据的数组,这个数组通过内存数组输出流的toByteArray方法获得,这个数组里面的数据其实就是已经被序列化成二进制数据的对象。最后创建一个ObjectInputStream反序列化流,并传入内存数组读取流,使用反序列化流的readobject方法将数组中的对象的信息,反序列化出来。反序列化出的对象就是一个新的对象,完成了深克隆。

当然还可以固定要被序列化对象的版本号,定义一个private static final long

serialVersionUID,但需要注意静态的成员和transient关键字修饰的成员不能被序列化。

三、使用开源工具类

比如Json工具类(先转换为Json字符串,然后再转换为对象)、Spring的BeanUtils(Spring项目中使用比较方便)、Cglib的BeanCopier(速度最快)、Apache的BeanUtils(该工具类比较慢,谨慎使用!)


版权声明:本文为weixin_36482113原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。