Search code examples
javacloneprivatesuper

Java - understanding cloning


This code was presented in my Computer Science class today (accompanying several questions irrelevant to this post). This is not homework, just some issues I personally found with the code;

public class CloneClass implements Cloneable {
    private Element element ;

    public CloneClass ( Element newElement ) {
        element = newElement ;
    }

    public CloneClass clone () {
        try {
            // I don't understand this
            CloneClass copy = ( CloneClass ) super.clone ();
            // or this
            copy.element = element.clone ();

            return copy ;
        } catch ( CloneNotSupportedException e ) {
            return null ;
        }
    }
}

Firstly;

CloneClass copy = ( CloneClass ) super.clone ();

We know that the super is Object (since there's no explicit extension) and that super.clone() must return an instance of CloneClass (it can't return an Object instance, since that's abstract, and it's being downcast to CloneClass, so it must be a CloneClass or descendant instance).
My question; how does super.clone() know to return a CloneClass instance?

Secondly;

copy.element = element.clone ();

How is it possible to directly refer to copy.element like that; it's declared as private!
It's not an attribute of the current class, it's an attribute of another instance (that happens to be the same class)

Thirdly;

} catch ( CloneNotSupportedException e ) {

Why is this needed? Is this incase Element doesn't extend Cloneable?


Solution

  • how does super.clone() know to return a CloneClass instance?

    Even within a super method, this still points to the same object, so this.getClass() will give you CloneClass (or even a subclass).

    How is it possible to directly refer to copy.element like that; it's declared as private!

    You can access private fields not just of this, but also of other instances of the same class. It is only private to other classes.

    Why is this needed? Is this incase Element doesn't extend Cloneable?

    Because CloneClass may not extend Cloneable (which it obviously does, but because of how this API has been designed with Object#clone throwing CloneNotSupportedException, the compiler cannot make this connection).

    This is a bit of an ugly design wart in Java. Object has a clone method, but Object itself is not Cloneable (which is a marker interface). So you can call the method on objects that don't support it. Similar thing with Serializable.