了解当我们使用和不使用super.clone覆盖克隆方法时会发生什么?

时间:2014-05-14 01:56:26

标签: java cloneable

我正在阅读Joshua Bloch的Effective Java。我必须说它是一本密集而复杂的书。关于所有对象共有的方法章节(第3章)对我来说很难掌握,因为我已经编程了不到3年(java中为1年)。我不太明白适当地覆盖克隆方法的概念。我是否可以通过简单的方式来实现克隆,正确的方式以及错误的方式?为什么未能调用super.clone会导致问题?会发生什么?

提前谢谢。

2 个答案:

答案 0 :(得分:1)

我自己正在读这本书。不确定我是否在这个例子中做了“正确”的事情,但也许它会帮助你理解。

Computer.java

package testclone;

public class Computer implements Cloneable {
    String OperatingSystem;

    protected Computer Clone() throws CloneNotSupportedException {
        Computer newClone = (Computer) super.clone();
        newClone.OperatingSystem = this.OperatingSystem;
        return newClone;
    }

}

MultiCore.java

package testclone;

public class MultiCore extends Computer implements Cloneable {
    int NumberOfCores;

    @Override
    protected MultiCore Clone() throws CloneNotSupportedException {
     //*********  use 1 of the next 2 lines  ***********           
        //MultiCore newClone = (MultiCore) super.clone();
        MultiCore newClone = new MultiCore();
        newClone.NumberOfCores = this.NumberOfCores;
        return newClone;
    }
}

TestClone.java

package testclone;

public class TestClone implements Cloneable {

    public static void main(String[] args) throws CloneNotSupportedException {
        //Computer myComputer = new Computer();
        //myComputer.OperatingSystem = "Windows";

        MultiCore myMultiCore = new MultiCore();
        myMultiCore.OperatingSystem = "Windows";    //field is in parent class
        myMultiCore.NumberOfCores = 4;

        MultiCore newMultiCore = myMultiCore.Clone();

        System.out.println("orig Operating System  = " + myMultiCore.OperatingSystem);
        System.out.println("orig Number of Cores   = " + myMultiCore.NumberOfCores);
        System.out.println("clone Operating System = " + newMultiCore.OperatingSystem);
        System.out.println("clone Number of Cores  = " + newMultiCore.NumberOfCores);

    }

}

输出:

orig操作系统= Windows

原子核数= 4

clone操作系统= null * 此行不是您想要的。

克隆核数= 4

如果使用super.clone()行,则输出为

orig操作系统= Windows

原子核数= 4

克隆操作系统= Windows * 现在它就是您想要的

克隆核数= 4

因此,如果你不使用super.clone(),它不会克隆父(或祖父母或曾祖父母等)中的字段

祝你好运! (对不起 - 当我输入时,上面看起来格式正确,但出于某种原因,当它实际显示时看起来很糟糕)

答案 1 :(得分:0)

您应始终使用super.clone()。如果你没有,只说return new MyObject(this.x);,那么这对MyObject的实例很有用。但是,如果某人扩展了MyObject,那么在覆盖clone方法时,他们再也无法获得正确类的实例。 Object.clone做的一件事就是你不能做好自己的工作就是创建一个合适的类的实例;剩下的只是复制实例字段,如果你愿意的话,这可能是你自己做的苦差事。