Non-final class defines a clone
method that does not call super.clone
.
class T implements Cloneable {
@Override
public Object clone() {
// Does not call super.clone();
T newObj = new T(...);
// ...
return newObj;
}
}
// ...
class U extends T implements Cloneable {
@Override
public Object clone() {
U newObj = (U)super.clone(); // This is an object of type T! This cast will fail with a ClassCastException.
// ...
return newObj;
}
}
If T
is extended by a subclass U
, and U
calls super.clone
, then it is likely that U
's clone
method will get an object of type T
. This will likely fail within the clone method itself when the subclass modifies data. Such code violates the standard contract for clone
as stated by the JavaDocs:
By convention, the returned object should be obtained by calling
super.clone
. If a class and all of its superclasses (exceptObject
) obey this convention, it will be the case thatx.clone().getClass() == x.getClass()
.
Always make sure to call super.clone
when implementing Cloneable
for any class.
class T implements Cloneable {
@Override
public Object clone() {
try {
T newObj = super.clone();
// ...
return newObj;
} catch (CloneNotSupportedException e) {
// ...
}
}
}