Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In clone() we use super.clone() then access a variable that is not in super, how comes?

Tags:

java

There is something that I don't understand in the usual implementation of the clone method. If you look at the first line in the try block in the following code, we are calling super.clone(), which will create an instance of the of the super class, and return an Object reference to that instance. Now, that instance does not necessarily contain hireDay, so how are we saying copy.hireDay? It is true that it will compile fine, but shouldn't it crash if the instance does not contain hireDay?

public Object clone() {
    try {
        Employee copy = (Employee) super.clone(); // copy ID, name, and salary!
        copy.hireDay = (Date) hireDay.clone();
        return copy;
    } catch (CloneNotSupportedException e) {
        System.out.println(e);
        return null;
    }
}
like image 748
Abdul Rahim Haddad Avatar asked Mar 22 '13 14:03

Abdul Rahim Haddad


2 Answers

The contract of clone is to achieve the same calling pattern as with constructors: the first step is always to call the superclass implementation. This results in Object.clone being invoked first and all subclasses use the instance returned by that method.

Object.clone will return an instance of the same class as the one being cloned. This happens by extralinguistic magic, basically by a bitwise copy of the memory block + necessary changes to the copy.

The cloning mechanism is fragile because any noncompliant class in the ancestor chain breaks cloning for all its descendants. This is one of several reasons why this mechanism is disfavored.

like image 152
Marko Topolnik Avatar answered Nov 01 '22 20:11

Marko Topolnik


clone() is a special method in the base Object class which creates a new instance of the correct base class type and copies all the fields (and avoids using any constructors). So, provided you don't have a custom parent class which does not delegate to Object.clone() you will always get the current type back.

As a side note, in your example, if super.clone() did not return an Employee, then your code would throw ClassCastException before you even got to the step where you reference hireDay.

like image 33
jtahlborn Avatar answered Nov 01 '22 22:11

jtahlborn