Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - downcast in clone

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!

like image 412
Hesham Yassin Avatar asked Sep 27 '13 09:09

Hesham Yassin


People also ask

Is Downcasting safe in Java?

Casting does not change the actual object type. Only the reference type gets changed. Upcasting is always safe and never fails. Downcasting can risk throwing a ClassCastException, so the instanceof operator is used to check type before casting.

Can you downcast objects in Java?

Downcasting is done using cast operator. To downcast an object safely, we need instanceof operator. If the real object doesn't match the type we downcast to, then ClassCastException will be thrown at runtime.

How to clone an object in Java?

Creating a copy using the clone() method The class whose object's copy is to be made must have a public clone method in it or in one of its parent class. Every class that implements clone() should call super. clone() to obtain the cloned object reference. The class must also implement java.

What is clone not supported exception?

The CloneNotSupportedException is an exception in Java that is thrown to indicate that the clone() method in class Object was called to clone an object, but that object's class does not implement the Cloneable interface.


1 Answers

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.

like image 162
Jon Skeet Avatar answered Nov 13 '22 11:11

Jon Skeet