开发者

Spring的BeanUtils.copyProperties属性复制避坑指南

目录
  • Spring的BeanUtils.copyProperties属性复制避坑
  • 问题描述
  • 结果分析
  • 结论

Spring的BeanUtils.copyProperties属性复制避坑

项目场景:

在分布式项目中,我进行我们的项目对外接口整合时,需要自己再定义对外的类来传参,就避免不了用BeanUtils.copyPrkUWLIMBptZopert编程客栈ies工具来进行属性赋值。

问题描述

关于BeanUtils.copyProperties的属性复制规则

话不多说直接上demo代码

  • 类A
class A {
    int a;
    List<Integer> list = new ArrayList<>();
    List<B> bList = new ArrayList<>();
    B b;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public List<Integer> getList() {
        return list;
    }

    public void setList(List<Integer> list) {
        this.list = list;
    }

    public List<B> getbList() {
        return bList;
    }

    public void setbList(List<B> bList) {
        this.bList = bList;
    }

   @Override
   public String toString() {
       return "A{" +
           "a=" + a +
           ", list=" + list +
           ", bList=" + bList +
           ", b=" + b +
           '}';
   }
}
  • 类A1
class A1 {
    int a;
    List<Integer> list = new ArrayList<>();
    List<B> bList = new ArrayList<>();
    B b;

    public int getA() {
        return a;
    }

    public void setA(int a) {
        this.a = a;
    }

    public B getB() {
        return b;
    }

    public void setB(B b) {
        this.b = b;
    }

    public List<Integer> getList() {
        return list;
    }

    public void setList(List<Integer> list) {
        this.list = list;
    }

    public List<B> getbList() {
        return bList;
    }

    public void setbList(List<B> bList) {
        this.bList = bList;
    }

    @Override
    public String toString() {
        return "A1{" +
            "a=" + a +
            ", list=" + list +
            ", bList=" + bList +
            ", b=" + b +
            '}';
    }
}
  • 类B
class B {
	String b;

    public String getB() {
      return b;
    }

	public void setB(String b) {
	  this.b = b;
	}

	@Override
	public String toString() {
	    return "B{" +
	        "b='" + b + '\'' +
	        '}';
	}
	
	public jsB() {
    }

    public B(String b) {
        this.b = b;
    }
}

测试main方法1

public static void main(String[] args) {
    A a = new A();

    B b = new B();
    b.setB("bbb");

    List<Integer> list = new ArrayList<>();
    list.add(100);
    list.add(200);

    List<B> bList = new ArrayList<>();
    bList.add(new B("dd"));
    bList.add(new B("cc"));
    bList.add(new B("ee"));

    a.setA(1);
    a.setB(b);
    a.setList(list);
    a.setbList(bList);

    A1 a1 = new A1();

    BeanUtils.copyProperties(a, a1);

    System.out.println(a1);
}

结果::A1{a=1, list=[100, 200], bList=[B{b=‘dd’}, B{b=‘cc’}, B{b=‘ee’}], b=B{b=‘bbb’}}

测试main方法2

public static void main(String[] args) {
   A a = new A();

    B b = new B();
    b.setB("bbb");

    List<Integer> list = new ArrayList<>();
    list.add(100);
    list.add(200);

    List<B> bList = new ArrayList<>();
    bList.add(new B("dd"));
    bList.add(new B("cc"));
    bList.add(new B("ee"));

    a.setA(1);
    a.setB(b);
    a.setList(list);
    a.setbList(bList);

    A1 a1 = new A1();

    BeanUtils.copyProperties(a, a1);

    b.setB("aaa");

    a.setA(2);

    list.clear();
    list.add(666);
    list.add(777);

    bList.clear();
    bList.add(new B("abc"));

    System.out.println(a1);
}

结果:A1{a=1, list=[666, 777], bList=[B{b=‘abc’}], b=B{b=‘aaa’}}

结果分析

从以上的例子和结果来看,BeanUtils.copyProperties是浅编程客栈拷贝。

  • main方法1: 当A和A1中的属性名称相同时,使用BeanUtils.copyProperties会将所有属性进行复制。从结果上来看,不管是基本数据类型int a,还是剩余的三个引用数据类型,List<Integer> listList<B> bListB b,都进行了复制。
  • main方法2 :第二个main方法在第一个的基础上对要复制的A的属性进行了修改,从结果上发现,A1的属性中基本数据类型int a的值并没有因为修改而改变,但引用数据类型List<Integer> listList<B> bListB b的值会因为改变了A的属性而改变。

附带两种对象属性复制的方法

// 浅拷贝
a1 = jsONObject.parseobject(JSONObject.toJSONString(a), A1.class)

// 深拷贝,其中SerializerFeature.DisableCircularReferenceDetect是为了解决JSON的$ref 引用
a1 = JSONObject.parseObject(JSONObject.toJSONString(a, SerializerFeature.DisableCircularReferenceDetect), A1.class);

// 深拷贝
ObjectMapper objectMapper = new ObjectMapper();
a1 = objectMapper.readValue(JSONObject.toJSONString(a, SerializerFeature.DisableCircularReferenceDetect), A1.classpython);

结论

BeanUtils.copyProperties的拷贝是浅拷贝,对基本数据类型进行值传递的属性复制,改变原基本数据类型的值不会改变被复制的属性结果;

对引用数据类型进行引用传递的属性复制,只是复制了一个内存地址过去,指向的还是同一个对象,并没有新建对象,改变原对象的值,被复制的属性的值也会随着变化。

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新开发

开发排行榜