BeanUtils.copyProperties()使用实例——Java对象的引用和赋值分析

BeanUtils.copyProperties()使用实例——Java对象的引用和赋值分析

前言

在最近一个项目开发中遇到了复制一个对象并修改其中一个属性值的情况,当时并没有意识到有什么问题,直到后面测试的时候发现不仅新对象的属性值改了,原对象的属性值也被修改了,这才意识到原来是犯了一个很基础的错误,于是在这里记录下对象引用、赋值问题的分析以及BeanUtils.copyProperties()方法的使用。

对象的引用

原理分析

对象是类所声明的变量,负责存放引用,以确保对象可以操作分配给该对象的变量以及调用类中的方法。

当我们直接new两个对象时,两个对象的引用是不同的,如下图
在这里插入图片描述
如果我们进行如下的赋值操作的话,两个对象就拥有了相同的引用,那么他们的引用指向相同的实体

object2 = object1;

此时它们的指向则变成
在这里插入图片描述
看到这里,大家应该就知道我前言中说的问题了,我将原对象的引用赋值给了新对象,此时这两个对象的引用是相同的也就是指向同一个实体,当我通过新对象去修改变量(属性)值时,就是修改了这个实体的变量值,因为原对象和新对象的引用都指向这个实体,所以就和我的需求不一样了

代码演示

这里先新建一个User类

package com.example.studytest.entity;

import lombok.Data;

/**
 * @Description:  User
 * @Author:       Olrookie
 * @Date:         2023/6/11
 */
@Data
public class User {
    
    

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private int age;

    /**
     * 性别
     */
    private String sex;
}

下面我们先复刻一下我的错误

public void test() {
    
    
        System.out.println("test开始执行!!");

        // 新建一个原对象sourceUser
        User sourceUser = new User();
        sourceUser.setName("小陈");
        sourceUser.setAge(25);
        sourceUser.setSex("女");

        System.out.println("原始sourceUser:" + sourceUser);

        // 新建一个对象tempUser,将原对象sourceUser的引用赋值给tempUser
        User tempUser = new User();
        tempUser = sourceUser;
        System.out.println("赋值后的tempUser:" + tempUser);
        // 通过新对象tempUser修改变量age的值
        tempUser.setAge(18);
        
        System.out.println("tempUser修改Age属性后的tempUser:" + tempUser);
        System.out.println("tempUser修改Age属性后的sourceUser:" + sourceUser);
    }

代码的输出的结果为:

test开始执行!!
原始sourceUser:User(name=小陈, age=25, sex=)
赋值后的tempUser:User(name=小陈, age=25, sex=)
tempUser修改Age属性后的tempUser:User(name=小陈, age=18, sex=)
tempUser修改Age属性后的sourceUser:User(name=小陈, age=18, sex=)

通过输出结果我们可以看到对象sourceUser的引用指向的实体的age也变成了18

BeanUtils.copyProperties()拷贝对象

这里我们直接通过代码来演示BeanUtils.copyProperties()拷贝对象,为了方便对比我们在上面的代码下再new一个对象

扫描二维码关注公众号,回复: 16795516 查看本文章
public void test() {
    
    
        System.out.println("test开始执行!!");

        // 新建一个原对象sourceUser
        User sourceUser = new User();
        sourceUser.setName("小陈");
        sourceUser.setAge(25);
        sourceUser.setSex("女");

        System.out.println("原始sourceUser:" + sourceUser);

        // 新建一个对象tempUser,将原对象sourceUser的引用赋值给tempUser
        User tempUser = new User();
        tempUser = sourceUser;
        System.out.println("赋值后的tempUser:" + tempUser);
        tempUser.setAge(18);
        System.out.println("tempUser修改Age属性后的tempUser:" + tempUser);
        System.out.println("tempUser修改Age属性后的sourceUser:" + sourceUser);

        // 新建一个对象targetUser,通过BeanUtils.copyProperties()方法进行对象拷贝
        User targetUser = new User();
        BeanUtils.copyProperties(sourceUser, targetUser);
        System.out.println("复制后的targetUser:" + targetUser);
        // 通过对象targetUser修改变量age
        targetUser.setAge(25);
        System.out.println("修改完Age属性后的targetUser:" + targetUser);
        System.out.println("targetUser修改完Age属性后的sourceUser:" + sourceUser);
    }

程序的输出结果为:

test开始执行!!
原始sourceUser:User(name=小陈, age=25, sex=)
赋值后的tempUser:User(name=小陈, age=25, sex=)
tempUser修改Age属性后的tempUser:User(name=小陈, age=18, sex=)
tempUser修改Age属性后的sourceUser:User(name=小陈, age=18, sex=)
复制后的targetUser:User(name=小陈, age=18, sex=)
修改完Age属性后的targetUser:User(name=小陈, age=25, sex=)
targetUser修改完Age属性后的sourceUser:User(name=小陈, age=18, sex=)

结合代码及输出结果我们可以得知:执行完**BeanUtils.copyProperties(sourceUser, targetUser);**后,targetUser和sourceUser输出的结果一样;再当我们通过targetUser修改了变量age为25后,targetUser和sourceUser输出的结果已经不一样了,此时他们的引用已经不同,也指向了不同的实体

结语

基础还是太重要了,自己学习只想着过一遍赶紧去实现需求从而忽略了重要的基础和原理。后面还是要慢慢填坑,以上作为这次问题的记录也是对自己一个警示,如有问题欢迎各位指出。

最后,祝大家变得更强!

猜你喜欢

转载自blog.csdn.net/weixin_55549435/article/details/131151057