java克隆对象-java对象转json对象
(1)克隆
implements可克隆
(2)连载
实现序列化
(3)利用反射机制复制
Apache 的 BeanUtils 解决方案
在使用 org.apache.commons.beanutils.BeanUtils 进行对象的深度复制时java克隆对象,主要是在 BeanUtils 框架中注入新的类型转换器,因为默认情况下,BeanUtils 通过引用复制复杂的对象,
可以发现,使用org.apache.commons.beanutils.BeanUtils复制引用时,主引用和源引用是一样的,即改变主引用属性会影响源引用,所以这是一个浅拷贝
Apache 的 PropertyUtils 方案
PropertyUtils的copyProperties()方法和BeanUtils.copyProperties()几乎一样。 主要区别在于后者提供了类型转换功能,即当发现两个同名的JavaBean属性属于不同类型时,可以在支持的数据类型范围内进行转换。 PropertyUtils 不支持这个特性,所以 BeanUtils 更常用,出错的风险更低。 而且它仍然是一个浅拷贝。
Apache提供了SerializationUtils.clone(T),T对象需要实现Serializable接口,属于深度克隆。
Spring的BeanUtils解决方案
BeanUtils在Spring中的实现非常简单java克隆对象,就是简单的获取/设置两个对象中的同名属性,只检查属性的可访问性。
可以看出,成员变量赋值是根据目标对象的成员列表进行的,ignore和那些在源对象中不存在的会被跳过,所以这种方法是安全的,不会因为结构差异而出错两个对象之间,但是同名的两个成员变量必须是同一类型。
推土机
Dozer() 可以实现深拷贝。 Dozer基于反射实现对象复制,调用set/get或者直接给成员变量赋值。 该方法通过invoke来执行赋值,一般使用beanutil、Javassist等开源库来实现。
地图结构
MapStrcut属于编译期对象复制方案,可以动态生成set/get代码的class文件,运行时直接调用class文件。 这个方法实际上会抛出set/get代码,但是你不需要自己写。
Bean 复印机
可以通过缓存 BeanCopier 实例来提高性能。
fastjson 和 GSON
fastjson和GSON的使用主要是通过对象json序列化和反序列化完成对象拷贝。 这里只是提供一个不同的对象复制思路,示例从略。
Spring的BeanUtils比较稳定,不会因为量大而显着增加耗时,但实际上benchmark耗时比较长; Apache的BeanUtils不够稳定高效,不可取; gson,因为做了两次gson转换,所以在正常项目中,可能耗时更少; PojoUtils不如spring稳定,但整体耗时优势明显,因为它只是根据项目需要实现的简单转换模板。 此代码在其他几个工具类中可用。
在网上的其他博客(见参考资料)中,已经对Apache的BeanUtils、PropertyUtils和CGLIB的BeanCopier进行了性能测试。
检测结果:
性能比较:BeanCopier > BeanUtils。 BeanCopier 的性能比其他两个高出 100 个数量级。
综上,推荐使用:
BeanUtils(简单易用)
BeanCopier(加入缓存后,性能接近手动设置)
推土机(深拷贝)
fastjson(特定场景使用)