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
?
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.