在克隆方法的常规实现中,我有些不明白的地方。 如果你看下面代码中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;
}
}
答案 0 :(得分:3)
clone()
是基类Object
类中的一种特殊方法,它创建正确基类类型的新实例并复制所有字段(并避免使用任何构造函数)。因此,如果您没有不委托给Object.clone()
的自定义父类,您将始终获得当前类型。
作为旁注,在您的示例中,如果super.clone()
不返回Employee
,那么您的代码将在您进入您所在的步骤之前抛出ClassCastException参考hireDay
。
答案 1 :(得分:3)
clone
的契约是实现与构造函数相同的调用模式:第一步始终是调用超类实现。这会导致首先调用Object.clone
,并且所有子类都使用该方法返回的实例。
Object.clone
将返回与正在克隆的类相同的类的实例。这通过语外魔术发生,基本上是通过内存块的按位复制+对副本的必要更改。
克隆机制很脆弱,因为祖先链中任何不合规的类都会破坏其所有后代的克隆。这是为什么这种机制不受欢迎的几个原因之一。