让我们说Class B
扩展class A
和class A
是可克隆的,如下所示:
public class A implements Cloneable {
public Object clone() throws CloneNotSupportedException {
A ac = (A) super.clone();
return ac;
}
}
public class B extends A {
public Object clone() throws CloneNotSupportedException {
B a = (B) super.clone();
return a;
}
}
为什么在下一行中从A到B进行向下转换是合法的:
B a = (B) super.clone(); // (super of B is A)
而下一次下线是运行时错误?
A a = new A();
B b = (B) a.clone();
提前致谢!
答案 0 :(得分:8)
最终,这是使用Object.clone()
来创建对象 - 并且保证创建一个与调用它的对象具有相同执行时类型的新对象:
类
clone
的方法Object
执行特定的克隆操作。首先,如果此对象的类未实现接口Cloneable
,则抛出CloneNotSupportedException
。请注意,所有数组都被视为实现接口Cloneable
,并且数组类型T[]
的克隆方法的返回类型是T[]
,其中T是任何引用或基本类型。否则,此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样;这些字段的内容本身不会被克隆。因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。
因此,如果我们在clone()
的实例上调用B
,那么super.clone()
将返回B
(或子类) - 所以是有效的。
在第二种情况下,您正在创建仅A
的实例,不 B
的实例,因此投射失败。