BeanUtils.copyProperties笔记

发布时间 2023-06-09 16:12:14作者: 懒阳阳是小学生

阿里开发者手册:

【强制】避免用 Apache Beanutils 进行属性的 copy。

说明:Apache BeanUtils 性能较差,可以使用其他方案比如 Spring BeanUtils, Cglib BeanCopier,注意均是浅拷贝。

本笔记使用的是:
org.springframework.beans.BeanUtils#copyProperties

资料参考: BeanUtils.copyProperties的使用

场景
开发中经常遇到,把父类的属性拷贝到子类中。通常有2种方法:
1、一个一个set
2、用BeanUtils.copyProperties
很显然BeanUtils更加方便,也美观很多。
那么任何情况都能使用BeanUtils么,当然不是。要先了解他。

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

什么情况适合用BeanUtils
如果都是单一的属性,那么不涉及到深拷贝的问题,适合用BeanUtils。

有子对象就一定不能用BeanUtils么
并不绝对,这个要区分考虑:
1、子对象还要改动。
2、子对象不怎么改动。
虽然有子对象,但是子对象并不怎么改动,那么用BeanUtils也是没问题的。

代码参考:

Teacher类
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    Integer id;
    public String name;
    private Integer gender;
}

 

Student类
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Student {
    Integer id;
    public String name;
    protected Integer gender;
    private Teacher teacher;
}

 

Test类

import org.junit.Test;
import org.springframework.beans.BeanUtils;

public class SpringBeanUtilsTest {

    @Test
    public void test01() {
        Teacher teacher01 = Teacher.builder().id(1).name("teacher1").gender(1).build();
        Student student01 = Student.builder().id(1).name("laoda").gender(0).teacher(teacher01).build();
        Student student02 = new Student();

        BeanUtils.copyProperties(student01, student02);

        System.out.println(student01);
        System.out.println(student02);
//        Student(id=1, name=laoda, gender=0, teacher=Teacher(id=1, name=teacher1, gender=1))
//        Student(id=1, name=laoda, gender=0, teacher=Teacher(id=1, name=teacher1, gender=1))

        teacher01.setName("teacher2");
        System.out.println(student01);
        // 注意观察teacher:name的值,只修改了student01中teacher:name,但是student02也跟着变了(BeanUtils.copyProperties为浅拷贝, 有子对象慎用)
        System.out.println(student02);
//        Student(id=1, name=laoda, gender=0, teacher=Teacher(id=1, name=teacher2, gender=1))
//        Student(id=1, name=laoda, gender=0, teacher=Teacher(id=1, name=teacher2, gender=1))
    }
}