java编程java对象copy

Posted 无信不立

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java编程java对象copy相关的知识,希望对你有一定的参考价值。

(1)克隆

implements Cloneable

(2)序列化

implements Serializable

 

(3)利用反射机制copy

apache的BeanUtils方案

使用org.apache.commons.beanutils.BeanUtils进行对象深入复制时候,主要通过向BeanUtils框架注入新的类型转换器,因为默认情况下,BeanUtils对复杂对象的复制是引用,

可以发现,使用org.apache.commons.beanutils.BeanUtils复制引用时,主和源的引用为同一个,即改变了主的引用属性会影响到源的引用,所以这是一种浅拷贝

apache的PropertyUtils方案

PropertyUtils的copyProperties()方法几乎与BeanUtils.copyProperties()相同,主要的区别在于后者提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,PropertyUtils不支持这个功能,所以说BeanUtils使用更普遍一点,犯错的风险更低一点。而且它仍然属于浅拷贝。

Apache提供了 SerializationUtils.clone(T),T对象需要实现 Serializable 接口,他属于深克隆。

 

spring的BeanUtils方案

Spring中的BeanUtils,其中实现的方式很简单,就是对两个对象中相同名字的属性进行简单get/set,仅检查属性的可访问性。

可以看到, 成员变量赋值是基于目标对象的成员列表, 并且会跳过ignore的以及在源对象中不存在的, 所以这个方法是安全的, 不会因为两个对象之间的结构差异导致错误, 但是必须保证同名的两个成员变量类型相同.

 

dozer

Dozer(http://dozer.sourceforge.net/)能够实现深拷贝。Dozer是基于反射来实现对象拷贝,反射调用set/get 或者是直接对成员变量赋值 。 该方式通过invoke执行赋值,实现时一般会采用beanutil, Javassist等开源库。

 

MapStrcut

MapStrcut属于编译期的对象复制方案,它能够动态生成set/get代码的class文件 ,在运行时直接调用该class文件。该方式实际上扔会存在set/get代码,只是不需要自己写了。

 

BeanCopier

可以通过缓存BeanCopier的实例来提高性能。

 

fastjson和GSON

使用fastjson和GSON主要是通过对象json序列化和反序列化来完成对象复制,这里只是提供一种不一样的对象拷贝的思路,例子略。

 

Spring的BeanUtils比较稳定,不会因为量大了,耗时明显增加,但其实基准耗时比较长;apache的BeanUtils稳定性与效率都不行,不可取;Gson,因为做两个gson转换,所以正常项目中,可能耗时会更少一些;PojoUtils稳定不如spring,但是总耗时优势明显,原因是它只是根据项目的需求,实现的简单的转换模板,这个代码在其它的几个工具类均有。

而在网上的其他Blog中(参见Reference),对Apache的BeanUtils、PropertyUtils和CGLIB的BeanCopier作了性能测试。

测试结果:

性能对比: BeanCopier > BeanUtils. 其中BeanCopier的性能高出另外两个100数量级。

综上推荐使用:

  1. BeanUtils(简单,易用)
  2. BeanCopier(加入缓存后和手工set的性能接近)
  3. Dozer(深拷贝)
  4. fastjson(特定场景下使用)

 

以上是关于java编程java对象copy的主要内容,如果未能解决你的问题,请参考以下文章

我想用java编一个计算器,面向对象编程

Java编程思想学习 一切都是对象

JAVA面向对象编程这本书的摘录~!(2016-5-23)

Java面向对象编程导论

Java面向对象编程

会一点java,有面向对象编程基础,选择入门unity有很大难度吗?应如何有效的入门?