1. 问题引出

工作中碰到这个一个问题

  1. public class CopyTest {
  2. public static void main(String[] args) throws Exception{
  3. A a = new A(2);
  4. B b = new B(2);
  5. C c = new C(a,b);
  6. C c1 = new C(new A(0),new B(0));
  7. BeanUtils.copyProperties(c1,c);
  8. c1.getA().setX(9);
  9. //可以发现a中的值也变化了
  10. System.out.println(c.getA().getX());
  11. System.out.println(a.getX());
  12. }
  13. }

这里问题的原因是:

  • BeanUtils.copyProperties(),是一个浅拷贝过程,C中有A和B两个对象
  • 浅拷贝给另一个C对象c1时,只会拷贝引用。
  • 最后c1对象去修改自己的属性对象a时,势必也会影响到别的引用到a的对象
  • 这是一个隐藏的小问题,很容易导致代码中出现意料不到的结果

注意目前发现,正常使用的BeanUtils.copyProperties的前提

  1. 涉及的类是public的,不是public的类,测试了,拷贝不会生效
  2. 类中要拷贝的数据,需要有get和set方法

浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并复制其内容

2 bean拷贝的常用方法

  • spring和apache中都有BeanUtils的实现
  • 最好使用Spring的BeanUtils,不要用Apache-Commons的BeanUtils。
  • Apache BeanUtils性能较差

  • 3. Java深拷贝的实现

  • 序列化再反序列

    • JSONObject.parseObject(input.toJSONString());
  • apache-commons包的SerializationUtils。
    • SerializationUtils要求对象必须实现序列化接口
    • 这个方法速度不快,1万次测试,本方法耗时5s+
    • JSONObject.parseObject(input.toJSONString()) 只要1s+