【问题标题】:Object Clone Shallow copy doesn't change variable对象克隆浅拷贝不改变变量
【发布时间】:2012-03-22 20:29:34
【问题描述】:

我试图克隆一个对象并更改新克隆对象的成员函数。如果是浅拷贝并且根据wiki页面,浅拷贝和原始对象指向同一个对象,那么它应该改变变量值。

    CloneExample obj1=new CloneExample();
    CloneExample obj2=(CloneExample) obj1.clone();
    obj1.a=2;
    obj1.c='a';
    System.out.println("obj1 real "+obj1.a+" "+obj1.c);
    System.out.println("obj2 real "+obj2.a+" "+obj2.c);
    obj2.a=99;
    obj2.c='z';
    System.out.println("obj2 after change "+obj2.a+" "+obj2.c);
    System.out.println("obj1 after change "+obj1.a+" "+obj1.c);
    System.out.println("obj1="+obj1+" obj2="+obj2);

如果这个克隆是浅拷贝,那么 obj2 和 Obj1 指向同一个引用 obj,改变 obj2 应该反映在 obj1 中。它不会发生。谁能解释一下(我知道克隆旨在给​​我们对象的副本,但如果它是浅拷贝,那么为什么我们需要浅拷贝?我们应该总是去深拷贝)。 谢谢你。

【问题讨论】:

    标签: java clone


    【解决方案1】:

    obj1 的浅拷贝创建另一个实例 obj2 您的 CloneExample 类 (obj1!=obj2)。 他们不共享价值成员。

    但是如果我们的类包含一个引用类型,例如java.util.Date,那么如果它们共享对该java.util.Date 的引用,那么更改它的值将反映在两个对象中。

    In Java, what is a shallow copy?

    【讨论】:

    • java.lang.Integer 是一个不好的例子,因为它是不可变的。以java.util.Date 为例。
    【解决方案2】:

    为什么你认为克隆是浅拷贝?看这里:http://docs.oracle.com/javase/6/docs/api/java/lang/Object.html#clone()

    正如它所说 - 克隆所做的是依赖于实现。此外,“浅拷贝”并不简单地创建对同一对象的新引用 - 通常它意味着创建一个新实例,其内部成员与复制的对象相同。但是,如果您更改新 obj 的成员变量以指向新对象,则不会更改原始 obj 的成员变量。

    【讨论】:

      【解决方案3】:

      当您调用 object.clone() 时,会创建新对象。因此,您将获得对该对象的引用。只有原始类型字段的对象可以完美克隆。因此,您可以完全独立于 obj1 副本。但是如果你的对象有引用的字段,你需要做一个深度克隆。

      【讨论】:

      • 您只需要深度克隆指向可变对象的引用字段。例如,String 字段是一个引用,但不需要深度克隆。
      猜你喜欢
      • 2011-09-05
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-09
      • 2014-07-02
      相关资源
      最近更新 更多