浅拷贝之copyProperties()

先说定义,

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝,此为浅拷贝

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

深拷贝与浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是深拷贝(值拷贝)),是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这时,你修改两个中的任意一个都不会影响另一个;而对于对象或引用数据在进行浅拷贝时,只是将对象的引用复制了一份,也就是内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任意一个变量的值都是改变内存地址所存储的值,因此两个变量的值都会改变。

简单来说,两者实际上都是为目标对象赋值,浅拷贝复制的是基本数据类型的数据以及引用类型的地址值,对于引用类型实际上是共用一个地址值(个人理解),深拷贝对于基本数据类型一样,对于引用类型是重新new了一个新对象并复制,用的是新的地址



举例:在项目中,我们常用beanUtils.copyProperties(),(不管是spring自带的还是apache的,都一样)来给具有较多相同字段的对象赋值,避免通过set的方式,开发效率较低过于繁琐,但是在bean对象结构较复杂,层级较多时会有一些问题,如下:

 我先定义一个User实体

@Data
public class User {
    private String username;
    private String password;
    private Address address;


    @Data
    public static class Address {
        private Integer menpaihao;
        private String jiedao;
        private List<Integer> numList;
    }
}

  然后进行测试

    @Test
    public void Test(){

        User user = new User();
        user.setUsername("张三");
        user.setPassword("123");
        User.Address address = new User.Address();
        address.setMenpaihao(110);
        address.setJiedao("成华大道");
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        address.setNumList(list);
        user.setAddress(address);

        User user1 = new User();
        BeanUtils.copyProperties(user,user1);
        System.out.println("user1 = " + user1);
        System.out.println("user = " + user);
        User user2 = initUser(user1);
        System.out.println("user = " + user);
        System.out.println("user2 = " + user2);
        
        System.out.println(VM.current().addressOf(user));
        System.out.println(VM.current().addressOf(user2));
        System.out.println("user的Address地址值 = " + VM.current().addressOf(user.getAddress()));     
        System.out.println("user2的Address的地址值 = " + VM.current().addressOf(user2.getAddress()));
    }

    public User initUser(User user){
        List<Integer> numList = user.getAddress().getNumList();
        for (int i = 0; i < numList.size(); i++) {
            numList.set(i,0);
        }
        return user;
    }

测试结果

可以发现将User复制到User1之后,我再对User1进行修改,改变它属下的numList里面的值,(而源对象User我一直是没有动过的),这时候再对两个进行打印,发现源对象User里面的属性值也被修改了,所以还是有点问题的。此时虽然最外层属性值没问题,地址也不一样,但是最内层的Address属性地址值是共用的,所以一变都变。

目前我的解决方式有两种,一种是老老实实通过set的方式一一赋值,效率还高,另一种就是通过深拷贝了。

深拷贝举例其中一种较简单的方式:

1. 导入依赖

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

2. 对bean对象以及其引用的其他实体类对象都要实现序列化

3.使用SerializationUtils.clone()克隆,返回的对象就是克隆后的对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值