java的深拷贝与浅拷贝及BeanUtils

关于深拷贝与浅拷贝原理这里不再赘述,

  • 浅拷贝就是对象的引用类型属性(除String外),object1的属性改变会牵连object2的属性改变,基本类型不变。

  • 而深拷贝就是完全隔离,属性变化互相不影响

可以参考这篇文章:java中的深浅拷贝基础l

这里要说的是我们平常使用的BeanUtils,无论是Spring框架提供的,还是Apache提供的(由于性能低,阿里的规范禁止使用),都是浅拷贝,使用的时候要注意这点。

验证一下,以Spring提供的BeanUtils为例:

public class Son {

    private String sonName;

    public String getSonName() {
        return sonName;
    }

    public void setSonName(String sonName) {
        this.sonName = sonName;
    }

    @Override
    public String toString() {
        return "Son{" +
                "sonName='" + sonName + '\'' +
                '}';
    }
}

public class Person {

    private String name;

    private int age;

    private Son son;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Son getSon() {
        return son;
    }

    public void setSon(Son son) {
        this.son = son;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", son=" + son +
                '}';
    }
}

import org.springframework.beans.BeanUtils;

public class Main {

    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setAge(20);
        p1.setName("小明");

        Son son = new Son();
        son.setSonName("小明的儿子");
        p1.setSon(son);

        System.out.println(p1);

        Person p2 = new Person();
        BeanUtils.copyProperties(p1, p2);
        System.out.println(p2);


        System.out.println("-----值变更后---");
        p1.getSon().setSonName("小强");
        p1.setAge(25);
        p1.setName("小强的儿子");

        System.out.println(p1);
        System.out.println(p2);
    }

}

结果如下:

Person{name='小明', age=20, son=Son{sonName='小明的儿子'}}
Person{name='小明', age=20, son=Son{sonName='小明的儿子'}}
-----值变更后---
Person{name='小强的儿子', age=25, son=Son{sonName='小强'}}
Person{name='小明', age=20, son=Son{sonName='小强'}}

可见,通过BeanUtils拷贝的对象属性,原来的值变了,会引起拷贝后对象的属性变化(仅限非String的引用类型

另外这里推荐使用SpringBeanUtils,不要用Apache的,原因参考:

为什么阿里巴巴禁止使用Apache Beanutils进行属性的copy?

你可能感兴趣的:(java基础增强)