Domanda

Lets say that Class B extends class A and class A is Cloneable as follows:

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;
    }
}

Why it is legal to perform down-cast from A to B in the next line:

B a = (B) super.clone(); // (super of B is A)

while the next down-cast is run-time error?

A a = new A();
B b = (B) a.clone();

Thanks in advance!

È stato utile?

Soluzione

Ultimately, this is using Object.clone() to create the object - and that's guaranteed to create a new object of the same execution-time type as the object it's called on:

The method clone for class Object performs a specific cloning operation. First, if the class of this object does not implement the interface Cloneable, then a CloneNotSupportedException is thrown. Note that all arrays are considered to implement the interface Cloneable and that the return type of the clone method of an array type T[] is T[] where T is any reference or primitive type. Otherwise, this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.

So if we get a call to clone() being executed on an instance of B, then super.clone() will return a B (or a subclass) - so the cast is valid.

In your second case, you're creating an instance of just A, which is not an instance of B, so the cast fails.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top