loader
20 May , 2020

BeanUtils.copyProperties深拷贝的使用

author

enthan809882 CSDN博客

shape animated shape animated shape animated

使用第三方账号注册

使用手机号/邮箱注册

BeanUtils.copyProperties深拷贝的使用。这里说的是 spring 的 BeanUtils.copyProperties。

场景

开发中经常遇到,把父类的属性拷贝到子类中。通常有 2 种方法:

1、一个一个 set;

2、用 BeanUtils.copyProperties;很显然 BeanUtils 更加方便,也美观很多。那么任何情况都能使用 BeanUtils 么,当然不是。要先了解他。

BeanUtils 是深拷贝,还是浅拷贝?

是浅拷贝。

浅拷贝: 只是调用子对象的 set 方法,并没有将所有属性拷贝。(也就是说,引用的一个内存地址)

深拷贝: 将子对象的属性也拷贝过去。

什么情况适合用 BeanUtils

如果都是单一的属性,那么不涉及到深拷贝的问题,适合用 BeanUtils。有子对象就一定不能用 BeanUtils 么并不绝对,这个要区分考虑:

1、子对象还要改动。

2、子对象不怎么改动。

虽然有子对象,但是子对象并不怎么改动,那么用 BeanUtils 也是没问题的。

代码例子

下面用代码说明下。

翠山有个儿子无忌,儿子继承了他的 face 和 height。

但是 life 应该是自己的。

后来翠山自刎而死,无忌也变成 dead 状态了。这就是浅拷贝,无忌用的 life 引用的翠山的 life 对象。

Father 类:

@Data
public class Father 
{
    private String face; // 长相
    private String height; // 身高
    private Life life; // 生命
}

Life 类:

@Data
public class Life 
{
    private String status;
}

Son 类和 main 方法:

@Data
public class Son extends Father
{
    private Life life;
    public static void main(String[] args) 
    {
        Father cuishan = new Father();
        cuishan.setFace("handsome");
        cuishan.setHeight("180");
        Life cuishanLife = new Life();
        cuishanLife.setStatus("alive");
        cuishan.setLife(cuishanLife);
        Son wuji=new Son();
        BeanUtils.copyProperties(cuishan,wuji);
        //Life wujiLife = wuji.getLife();
        //wujiLife.setStatus("alive");
        //wuji.setLife(wujiLife);
        //cuishanLife.setStatus("dead"); // 翠山后来自刎了
        System.out.println(JSON.toJSONString(cuishan));
        System.out.println(JSON.toJSONString(wuji));
    }
}

上面注释出的代码可以如下替换:

case1 和 case2 还是受浅拷贝的影响,case3 不受。

case1: 翠山自刎,无忌也挂了

//Life wujiLife = wuji.getLife();
//wujiLife.setStatus("alive");
//wuji.setLife(wujiLife);
//cuishanLife.setStatus("dead"); // 翠山后来自刎了

case2: 翠山自刎,无忌设置或者,翠山也活了

//cuishanLife.setStatus("dead"); // 翠山后来自刎了
//Life wujiLife = wuji.getLife();
//wujiLife.setStatus("alive");
//wuji.setLife(wujiLife);

case3: 翠山和无忌互不影响

cuishanLife.setStatus("dead"); // 翠山自刎了  该行放在上下均可
// 无忌用个新对象 不受翠山影响了
Life wujiLife = new Life();
wujiLife.setStatus("alive");
wuji.setLife(wujiLife);

BeanUtils.copyProperties深拷贝

/**
 * 对象属性拷贝 <br>
 * 将源对象的属性拷贝到目标对象
 *
 * @param source 源对象
 * @param target 目标对象
 */
public static void copyProperties(Object source, Object target) 
{
    try {
        BeanUtils.copyProperties(source, target);
    } catch (BeansException e) {
        LOGGER.error("BeanUtil property copy  failed :BeansException", e);
    } catch (Exception e) {
        LOGGER.error("BeanUtil property copy failed:Exception", e);
    }
}

BeanUtils.copyProperties深拷贝小结

1. 深拷贝和浅拷贝

深拷贝,相当于创建了一个新的对象,只是这个对象的所有内容,都和被拷贝的对象一模一样而已,即两者的修改是隔离的,相互之间没有影响

浅拷贝,也是创建了一个对象,但是这个对象的某些内容(比如A)依然是被拷贝对象的,即通过这两个对象中任意一个修改A,两个对象的A都会受到影响,等同与新创建一个对象,然后使用=,将原对象的属性赋值给新对象的属性需要实现Cloneable接口。

2. 对象拷贝的两种方法

通过反射方式实现对象拷贝,主要原理就是通过反射获取所有的属性,然后反射更改属性的内容。通过代理实现对象拷贝将原SourceA拷贝到目标DestB,创建一个代理 copyProxy。在代理中,依次调用 SourceA的get方法获取属性值,然后调用DestB的set方法进行赋值。

Robin Binar Themeix

Onubia, turpis inceptos pharetra. Ipsum erat rutrum, luctus non rhoncus quam quisque posuere, eros pede leo facilisis at risus. Ea sit consectetuer suscipit pede hac purus, erat nec

猜你喜欢

WinSxS是什么,C盘WinSxS是什么文件夹?

11 Dec , 2018

2018-12-11 00:01

mac下安装composer,macos系统下全局安装composer

11 Dec , 2018

2018-12-11 00:11

区块链是什么,区块链到底是什么意思,看完这段话就懂了

11 Dec , 2018

2018-12-11 00:19

wireshark使用教程,网络抓包工具wireshark中文版使用教程

11 Dec , 2018

2018-12-11 00:48

VBS整人代码大集合,学会用VBS来编小程序对心仪的女神表白

11 Dec , 2018

2018-12-11 02:06

网友评论 ( 0 条评论 )

评论