简体   繁体   English

了解我们在调用super.clone和不调用super.clone时覆盖clone方法时会发生什么情况?

[英]Understanding what happens when we override the clone method with and without invoking super.clone?

I'm reading Effective Java by Joshua Bloch. 我正在阅读Joshua Bloch撰写的Effective Java。 I must say its a dense and complex book. 我必须说这是一本密集而复杂的书。 The chapter on Methods Common to all objects (chapter 3) is proving hard for me to grasp as I've been programming for less than 3 years (1 year in java). 事实证明,对于我来说,不到3年的编程时间(在Java中为1年),对所有对象通用的方法(第3章)这一章非常困难。 I don't quite understand the concept of overriding the clone method appropriately. 我不太了解适当重写克隆方法的概念。 Can I get a simple to follow example of implementing clone, the right way as well as the wrong way? 我可以得到一个简单易懂的示例来实现克隆,正确和错误的方法吗? And why failing to invoke super.clone would cause a problem? 为什么不能调用super.clone会导致问题? what will happen? 会发生什么?

Thank you in advance. 先感谢您。

I'm reading that book myself. 我自己在读书。 Not sure if I did everything "right" in this example, but maybe it'll help you understand. 不知道在这个例子中我是否做对了所有事情,但是也许会对您有所帮助。

Computer.java 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 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 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);

    }

}

Output: 输出:

orig Operating System = Windows orig操作系统= Windows

orig Number of Cores = 4 orig核心数= 4

clone Operating System = null * This line is not what you want. clone操作系统= null *此行不是您想要的。

clone Number of Cores = 4 克隆核心数= 4

If you use the super.clone() line instead, then the Output is 如果改用super.clone()行,则输出为

orig Operating System = Windows orig操作系统= Windows

orig Number of Cores = 4 orig核心数= 4

clone Operating System = Windows * Now it's what you want clone操作系统= Windows *现在就是您想要的

clone Number of Cores = 4 克隆核心数= 4

So if you don't use super.clone(), it doesn't clone the fields in the parent (or grandparent, or great-grandparent, etc) 因此,如果您不使用super.clone(),它将不会在父级(或祖父母级或曾祖父母级等)中克隆字段

Good luck! 祝好运! (Sorry - the above looked formatted correctly when I typed it in, but for some reason looks awful when it actually shows) (抱歉-上面键入的内容看起来格式正确,但是由于实际原因,它看起来很糟糕)

You should always use super.clone() . 您应该始终使用super.clone() If you don't, and say just return new MyObject(this.x); 如果不这样做,请说return new MyObject(this.x); , then that works fine for instances of MyObject. ,那么对于MyObject实例来说效果很好。 But if someone extends MyObject, it's no longer possible for them to get an instance of the right class when overriding your clone method. 但是,如果有人扩展了MyObject,则在覆盖clone方法时,他们将再也无法获得正确的类的实例。 The one thing Object.clone does that you can't do a good job of yourself is creating an instance of the right class; Object.clone所做的一件事情是您无法做好自己的工作,即创建了正确的类的实例。 the rest is just copying instance fields, which is drudgework you could have done yourself if you wanted. 其余的只是复制实例字段,这是繁琐的工作,您可以根据需要自己完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM