I have a quick question regarding the clone()
method in Java, used as super.clone()
in regard to inheritance - where I call the clone()
Although one answer is accepted, I do not think it fully answers the first part of the question (why downcasting in subclasses always works). Although I cannot really explain it, I think I can clear up some of the poster's confusion which was the same as mine. We have the following classes
class A implements Cloneable
{
@Override
protected A clone() throws CloneNotSupportedException // could be public
{
Object clone = super.clone();
System.out.println("Class A: " + clone.getClass()); // will print 'C'
return (A) clone;
}
}
class B extends A
{
@Override
protected B clone() throws CloneNotSupportedException
{
A clone = super.clone();
System.out.println("Class B: " + clone.getClass()); // will print 'C'
return (B) clone;
}
}
class C extends B
{
@Override
protected C clone() throws CloneNotSupportedException
{
B clone = super.clone();
System.out.println("Class C: " + clone.getClass()); // will print 'C'
return (C) clone;
}
}
static main(char[] argv)
{
C c = new C();
C cloned_c = c.clone();
}
The result of this is that
Class A: C
Class B: C
Class C: C
is printed on the command line.
So, as a matter of fact, the clone()
method of Object
somehow can look down the call stack and see which type of object at the start of the chain invoked clone()
, then, provided the calls bubble up so that Object#clone()
is actually called, an object of that type is created. So this happens already in class C
, which is strange, but it explains why the downcasts do not result in a ClassCastException
. I've checked with the OpenJDK, and it appears this comes by some Java black magic implemented in native code.