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

There is something that I don’t understand in the usual implementation of the clone method. If you look at the first line of a try block in the following code, we call super.clone (), which will create an instance of the superclass and return an Object reference to that instance. Now this instance does not necessarily contain findDay, so how do we say copy.hireDay? It is true that it will compile fine, but should it not crash if the instance does not contain findDay?

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; } } 
+6
source share
2 answers

The clone contract is to achieve the same calling pattern as with the constructors: the first step is always to call the implementation of the superclass. This causes Object.clone called first, and all subclasses use the instance returned by this method.

Object.clone will return an instance of the same class as the cloned one. This is due to extralinguistic magic, mainly through a bitwise copy of a memory block + necessary changes to the copy.

The cloning mechanism is fragile because any incompatible class in the chain of ancestors destroys cloning for all its descendants. This is one of several reasons why this mechanism is not welcome.

+3
source

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

As an example, note that if super.clone() did not return Employee , then your code will throw a ClassCastException before you get to the step you refer to hireDay .

+3
source

All Articles