6

在克隆方法的通常实现中,有一些我不明白的地方。如果您查看以下代码中 try 块的第一行,我们正在调用 super.clone(),它将创建超类的实例,并返回对该实例的 Object 引用。现在,该实例不一定包含hireDay,那么我们怎么说copy.hireDay?确实它会编译得很好,但是如果实例不包含hireDay,它不应该崩溃吗?

public Object clone() {
    try {
        Employee copy = (Employee) super.clone(); // copy ID, name, and salary!
        copy.hireDay = (Date) hireDay.clone();
        return copy;
    } catch (CloneNotSupportedException e) {
        System.out.println(e);
        return null;
    }
}
4

2 回答 2

3

clone()是基类中的一个特殊方法,Object它创建正确基类类型的新实例并复制所有字段(并避免使用任何构造函数)。因此,如果您没有委托给Object.clone()您的自定义父类,则始终会返回当前类型。

作为旁注,在您的示例中,如果super.clone()没有返回,那么Employee您的代码甚至会在您到达引用的步骤之前抛出 ClassCastException hireDay

于 2013-03-22T14:13:32.283 回答
3

的约定clone是实现与构造函数相同的调用模式:第一步始终是调用超类实现。这导致Object.clone首先被调用,并且所有子类都使用该方法返回的实例。

Object.clone将返回与被克隆的类相同的实例。这是通过语言外的魔法发生的,基本上是通过内存块的按位副本 + 对副本进行必要的更改。

克隆机制很脆弱,因为祖先链中的任何不兼容类都会破坏其所有后代的克隆。这是该机制不受欢迎的几个原因之一。

于 2013-03-22T14:16:53.913 回答