0

我正在阅读 Joshua Bloch 的《Effective Java》。我必须说这是一本密集而复杂的书。事实证明,关于所有对象通用方法的章节(第 3 章)对我来说很难掌握,因为我已经编程不到 3 年(Java 中的 1 年)。我不太了解适当覆盖克隆方法的概念。我能得到一个简单易懂的实现克隆的例子,正确的方法和错误的方法吗?为什么不调用 super.clone 会导致问题?会发生什么?

先感谢您。

4

2 回答 2

1

我自己在看那本书。不确定我在这个例子中是否做的一切都“正确”,但也许它会帮助你理解。

计算机.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;
    }

}

多核.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;
    }
}

测试克隆.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);

    }

}

输出:

原始操作系统 = Windows

核心数 = 4

clone Operating System = null * 这行不是你想要的。

克隆核心数 = 4

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

原始操作系统 = Windows

核心数 = 4

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

克隆核心数 = 4

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

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

于 2014-05-14T03:44:54.463 回答
0

您应该始终使用super.clone(). 如果你不这样做,只是说return new MyObject(this.x);,那么这对于 MyObject 的实例来说很好。clone但是,如果有人扩展了 MyObject,则在覆盖您的方法时,他们将不再可能获得正确类的实例。Object.clone 做的一件你不能做好自己的事情是创建正确类的实例;其余的只是复制实例字段,如果您愿意,您可以自己完成这项苦差事。

于 2014-05-14T02:14:19.917 回答