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!
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 classObject
performs a specific cloning operation. First, if the class of this object does not implement the interfaceCloneable
, then aCloneNotSupportedException
is thrown. Note that all arrays are considered to implement the interfaceCloneable
and that the return type of the clone method of an array typeT[]
isT[]
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.