Java - 在克隆中贬低

Hes*_*sin 7 java inheritance clone downcast

让我们说,Class B扩展class Aclass 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么在下一行中从A到B进行向下转换是合法的:

B a = (B) super.clone(); // (super of B is A)
Run Code Online (Sandbox Code Playgroud)

而下一个下线是运行时错误?

A a = new A();
B b = (B) a.clone();
Run Code Online (Sandbox Code Playgroud)

提前致谢!

Jon*_*eet 9

最终,这Object.clone()用于创建对象 - 并且保证创建与其调用的对象具有相同执行时类型的新对象:

clone类的方法Object执行特定的克隆操作.首先,如果此对象的类未实现接口Cloneable,则CloneNotSupportedException抛出a.请注意,所有数组都被认为是实现接口,Cloneable并且数组类型的clone方法的返回类型T[]T[]T是任何引用或基本类型.否则,此方法创建此对象的类的新实例,并使用该对象的相应字段的内容初始化其所有字段,就像通过赋值一样; 这些字段的内容本身不会被克隆.因此,该方法执行该对象的"浅拷贝",而不是"深拷贝"操作.

因此,如果我们调用clone()在一个实例上执行B,那么super.clone()将返回一个B(或子类) - 因此强制转换是有效的.

在第二种情况下,您正在创建一个just的实例A,它不是实例B,因此转换失败.

  • @HeshamYassin:不,`A.clone()`返回一个至少*是'A`的引用 - 这就是强制转换为'A`的保证.但它实际上*将是一个`B`(或子类),因为你正在克隆一个'B`的实例.查看调试器中`ac`的值,你会看到它是对'B`实例的引用. (2认同)