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> list
、List<B> bList
、B b
,都进行了复制。 - main方法2 :第二个main方法在第一个的基础上对要复制的A的属性进行了修改,从结果上发现,A1的属性中基本数据类型
int a
的值并没有因为修改而改变,但引用数据类型List<Integer> list
、List<B> bList
、B 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的拷贝是浅拷贝,对基本数据类型进行值传递的属性复制,改变原基本数据类型的值不会改变被复制的属性结果;
对引用数据类型进行引用传递的属性复制,只是复制了一个内存地址过去,指向的还是同一个对象,并没有新建对象,改变原对象的值,被复制的属性的值也会随着变化。
精彩评论