As you rightly point out, the convention should always call super.clone() at the beginning of the implementation of clone() . From the docs API to Object#clone() :
By convention, the returned object must be received by calling super.clone. If a class and all its superclasses (except Object) obey this convention, this will be the case when x.clone (). GetClass () == x.getClass ().
Your first attempt (without using super.clone() ) has the following problem:
Let's pretend that
class IntDoubleLinkedList extends DoubleLinkedList<Integer> implements Cloneable
(and that IntDoubleLinkedList does not get the clone() override), and I run the following code:
IntDoubleLinkedList idll = new IntDoubleLinkedList(); IntDoubleLinkedList idll2 = (IntDoubleLinkedList) idll.clone();
What will happen? The clone method of your DoubleLinkedList will be executed, which, if it does not go through super.clone (), returns an instance of DoubleLinkedList , which, in turn, cannot be sent to the IntDoubleLinkedList . A ClassCastException will be thrown!
So how super.clone() solve this problem? Well, if everyone adheres to the convention of calling super.clone() in the overriden clone method, Object.clone() will eventually be called, and this implementation will instantiate the appropriate type ( IntDoubleLinkedList in this case)!
source share