龙空技术网

对象拷贝java 浅谈

开始自媒体 93

前言:

如今看官们对“java如何复制文件”大约比较注重,兄弟们都需要学习一些“java如何复制文件”的相关资讯。那么小编同时在网上汇集了一些对于“java如何复制文件””的相关内容,希望你们能喜欢,姐妹们快快来学习一下吧!

1 前言

对象拷贝,是我们在开发过程中,绕不开的过程,既存在于 Po、Dto、Do、Vo 各个表现层数据的转换,也存在于系统交互如序列化、反序列化。

Java 对象拷贝分为深拷贝和浅拷贝,目前常用的属性拷贝工具,包括 Apache 的 BeanUtils、Spring 的 beanUtils、Cglib 的 BeanCopier、mapstruct 都是浅拷贝。

1.1 深拷贝

深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容称为深拷贝。

深拷贝常见有以下四种实现方式:

构造函数Serializable 序列化实现 Cloneable 接口JSON 序列化

1.2 浅拷贝

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝称为浅拷贝。通过实现 Cloneabe 接口并重写 Object 类中的 clone () 方法可以实现浅克隆。

2 常用对象拷贝工具原理剖析及性能对比

目前常用的属性拷贝工具,包括 Apache 的 BeanUtils、spring 的 BeanUtils、cglib 的 BeanCopier、mapstruct。

Apache BeanUtils:BeanUtils 是 Apache commons 组件里面的成员,由 Apache 提供的一套开源 api,用于简化对 javaBean 的操作,能够对基本类型自动转换。Spring BeanUtils:BeanUtils 是 spring 框架下自带的工具,在 org.Springframework.beans 包下, spring 项目可以直接使用。Cglib BeanCopier:cglib(Code Generation Library)是一个强大的、高性能、高质量的代码生成类库,BeanCopier 依托于 cglib 的字节码增强能力,动态生成实现类,完成对象的拷贝。mapstruct:mapstruct 是一个 Java 注释处理器,用于生成类型安全的 bean 映射类,在构建时,根据注解生成实现类,完成对象拷贝。2.1 原理分析

2.1.1 Apache BeanUtils

使用方式:BeanUtils.copyProperties (target, source);

BeanUtils.copyProperties 对象拷贝的核心代码如下:

// 1.获取源对象的属性描述PropertyDescriptor[] origDescriptors = this.getPropertyUtils().getPropertyDescriptors(orig);PropertyDescriptor[] temp = origDescriptors;int length = origDescriptors.length;String name;Object value;// 2.循环获取源对象每个属性,设置目标对象属性值for(int i = 0; i < length; ++i) {PropertyDescriptor origDescriptor = temp[i];name = origDescriptor.getName();// 3.校验源对象字段可读切目标对象该字段可写if (!"class".equals(name) && this.getPropertyUtils().isReadable(orig, name) && this.getPropertyUtils().isWriteable(dest, name)) {try {// 4.获取源对象字段值value = this.getPropertyUtils().getSimpleProperty(orig, name);// 5.拷贝属性this.copyProperty(dest, name, value);} catch (NoSuchMethodException var10) {}}}

循环遍历源对象的每个属性,对于每个属性,拷贝流程为:

校验来源类的字段是否可读 isReadable校验目标类的字段是否可写 isWriteable获取来源类的字段属性值 getSimpleProperty获取目标类字段的类型 type,并进行类型转换设置目标类字段的值

由于单字段拷贝时每个阶段都会调用 PropertyUtilsBean.getPropertyDescriptor 获取属性配置,而该方法通过 for 循环获取类的字段属性,严重影响拷贝效率。

获取字段属性配置的核心代码如下:

PropertyDescriptor[] descriptors = this.getPropertyDescriptors(bean);if (descriptors != null) {for (int i = 0; i < descriptors.length; ++i) {if (name.equals(descriptors[i].getName())) {return descriptors[i];}}}
2.1.2 Spring BeanUtils

使用方式: BeanUtils.copyProperties (source, target);

BeanUtils.copyProperties 核心代码如下:

标签: #java如何复制文件