用Java克隆对象

时间:2014-10-18 10:06:08

标签: java clone

摘自Herbert Schildt关于Java的书

  

克隆是一种潜在的危险行为,因为它可以       导致意想不到的副作用。例如,如果是对象       被克隆包含一个名为obRef的引用变量,       然后在制作克隆时,克隆中的obRef将引用       与原始中的obRef相同的对象。       如果克隆对对象的内容进行了更改       由obRef引用,那么它也将被改变为原始对象。

因此,当克隆对象时,请执行指向该对象的引用 原始对象也被克隆,因此这些指向克隆对象?

我对此行感到困惑" ...克隆中的obRef将引用     与原始中的obRef相同的对象..."。

2 个答案:

答案 0 :(得分:2)

考虑对原始对象的引用与原始对象中的之间的区别。

假设您有myObj类型的对象MyClass,其中包含名为myList的ArrayList类型的字段。

构造此对象时,myList已使用new ArrayList()进行初始化,现在指向VM堆中的对象。

现在假设您克隆myObj

MyClass myClone = myObj.clone();

变量myClone指向与myObj不同的对象。它们是两个不同的对象。但是,myList内的myObj字段将指向堆中的同一对象myList中为myClone。这是因为当您克隆时,引用按原样复制,没有new ArrayList()在新对象中为myList分配单独的对象。

没有任何引用会自动更改,因此对旧版myObj的任何引用仍然指向它。在将新对象分配给其他变量之前,对新对象的唯一引用是myClone。但myList也是如此。所以这两个对象指向相同的ArrayList。因此,如果其中一个添加到它,另一个看到添加的值。

通常情况下,这不是你需要的。

答案 1 :(得分:0)

让我们说,我有一个名为Another的课程如下所示:

public class Another {
     int number;
     String message;
     // And so on.
}

另一个名为CloneMe的类重写了clone()方法,如图所示:

public class CloneMe {
   int version;
   Another another;

   public CloneMe(int newVersion, Another obj) {
       this.version = newVersion;
       this.another = obj;
   }
   // and so on

   @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone(); // You can also provide your own implementation here
    }
}

现在,当您创建类 CloneMe 的对象时:

  CloneMe actualObject = new CloneMe(10, new Another());

然后创建一个类另一个的实例,并将其分配给CloneMe类中的另一个

现在,当你致电:

  CloneMe clonedObject = actualObject.clone();

然后,只使用 actualObject 的现有状态创建 CloneMe 的新实例。但是,没有创建任何其他类的新实例(例如,在我们的示例中为Another),但是将相同的对象引用分配给 clonedObject 中的引用变量。这称为浅层克隆