Exemplo de uso de BeanUtils.copyProperties() - referência de objeto Java e análise de atribuição

Exemplo de uso de BeanUtils.copyProperties() - referência de objeto Java e análise de atribuição

Prefácio

Durante o desenvolvimento de um projeto recente, me deparei com a situação de copiar um objeto e modificar um de seus valores de atributos. Não percebi que havia algum problema naquele momento. Só mais tarde, durante os testes, descobri que não apenas o valor do atributo do novo objeto foi alterado, mas também o valor do atributo do objeto original. Após ser modificado, percebi que havia cometido um erro muito básico, então registrei a análise das referências do objeto e problemas de atribuição e o uso do método BeanUtils.copyProperties().

referência de objeto

Análise de princípios

Objetos são variáveis ​​declaradas por uma classe e são responsáveis ​​por armazenar referências para garantir que o objeto possa operar as variáveis ​​atribuídas ao objeto e chamar métodos na classe.

Quando criamos dois objetos diretamente, as referências dos dois objetos são diferentes, conforme mostrado abaixo:
Insira a descrição da imagem aqui
Se realizarmos a seguinte operação de atribuição, os dois objetos terão a mesma referência e suas referências apontam para a mesma entidade.

object2 = object1;

Neste momento, o apontamento deles se torna
Insira a descrição da imagem aqui
Aqui, todos devem saber o problema que mencionei no prefácio. Atribuí a referência do objeto original ao novo objeto. Neste momento, as referências dos dois objetos são as mesmas, ou seja, eles apontam para Para a mesma entidade, quando modifico o valor da variável (atributo) através de um novo objeto, o valor da variável desta entidade é modificado.Porque as referências do objeto original e do novo objeto apontam para esta entidade, é diferente das minhas necessidades.

demonstração de código

Aqui primeiro crie uma nova classe de usuário

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;
}

Vamos reproduzir meu erro primeiro

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);
    }

A saída do código é:

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=)

Através dos resultados de saída, podemos ver que a idade da entidade apontada pela referência do objeto sourceUser também passou a ser 18.

Objeto de cópia BeanUtils.copyProperties()

Aqui demonstramos diretamente BeanUtils.copyProperties() copiando objetos por meio de código. Para conveniência de comparação, criamos um novo objeto no código acima.

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);
    }

A saída do programa é:

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=)

Combinando o código e os resultados de saída, podemos saber: Depois de executar **BeanUtils.copyProperties(sourceUser, targetUser);**, os resultados de saída de targetUser e sourceUser são os mesmos; e então quando modificamos a variável age para 25 através de targetUser , targetUser e Os resultados gerados por sourceUser não são mais os mesmos. Neste momento, suas referências são diferentes e apontam para entidades diferentes.

Conclusão

O básico ainda é muito importante. Quando você aprende sozinho, você só quer repassar e perceber rapidamente as necessidades, ignorando assim os fundamentos e princípios importantes. Ainda terei que preencher os buracos lentamente no futuro. O registro acima desse problema também é um aviso para mim mesmo. Se houver algum problema, você pode apontá-lo.

Finalmente, desejo que todos se tornem mais fortes!

Acho que você gosta

Origin blog.csdn.net/weixin_55549435/article/details/131151057
Recomendado
Clasificación