BeanCopy 常用工具类


 

Bean Copy常见工具类

硬编码

手动get、set,性能最高,但写起来麻烦。

 

MapStruct(推荐)
  • 需要引入依赖、自行定义mapper接口;
  • 编译时自动生成硬编码方式的拷贝,性能几乎可以媲美硬编码;
  • 可以拷贝普通对象、Collection,不能拷贝Map;
  • 支持自定义转换,扩展性好;

使用可参考:https://blog.csdn.net/chy_18883701161/article/details/127916574

 

cglib的BeanCopier
  • 基于动态代理实现,性能不错;支持自定义转换器,可扩展;
  • 只能拷贝普通对象,不能拷贝Collection、Map
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
//参数依次指定源类、目标类、是否使用转换器
BeanCopier beanCopier = BeanCopier.create(UserOrderBo.class, UserOrderVo.class, false);
//参数分别为source、target、转换器,返回值void,需要目标对象已存在
beanCopier.copy(userOrderBo, userOrderVo, null);

 

spring-beans的BeanUtils
  • 基于反射实现,性能一般;
  • 只能拷贝普通对象,不能拷贝Collection、Map
//参数依次指定source、target,返回值void,需要target已存在
BeanUtils.copyProperties(userBo, userVo);

//可以指定要忽略的属性,参数个数可变
BeanUtils.copyProperties(userBo, userVo, "password", "tel");

 

apache的BeanUtils

基于反射实现,性能极差,避免使用

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
</dependency>

 

浅拷贝与深拷贝

拷贝都是新建目标类实例,浅拷贝、深拷贝的区别在于引用类型的成员字段的复制方式不同

  • 浅拷贝:字段都是直接拷贝引用(地址),和原成员字段指向的堆中的同一个对象,优点是开销小、速度快、性能好,缺点是通过其中一个引用修改堆中对象时,会影响到指向这个对象的其它引用;
  • 深拷贝:引用类型的成员变量会重新创建实例,开销大、速度慢,但更安全,可以避免共用堆中对象导致的问题。

以上介绍的几种bean copy方式都是浅拷贝,通常出于性能考虑,也是使用浅拷贝,除非特殊情况

 

使用Object的clone()方法实现浅拷贝

根类 Object 的 clone() 方法是 native 方法,速度快、性能高

//实现标记接口 Cloneable
public class User implements Cloneable {

    //修改访问权限为public,把返回值转换为具体类型,方法体中调用根类Object的clone()方法
    @Override
    public User clone() throws CloneNotSupportedException {
        return (User) super.clone();
    }

}

 

通过反序列化实现深拷贝

反序列化是深拷贝的,这也是实现深拷贝最常见的方式

/**
 * 操作对象的工具类
 */
public class ObjectUtil {

    /**
     * 深拷贝对象
     *
     * @param source 源对象
     * @param <T>    目标类型
     * @return 深拷贝得到的对象
     * @throws IOException, ClassNotFoundException
     */
    public static <T> T deepClone(T source) throws IOException, ClassNotFoundException {
        //序列化源对象
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(source);

        //反序列化得到新对象
        ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bais);
        T target = (T) ois.readObject();

        ois.close();
        oos.close();
        return target;
    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值