Why is this an issue?
Cloneable
is the marker Interface
that indicates that clone()
may be called on an object. Overriding
clone()
without implementing Cloneable
can be helpful if you want to control how subclasses clone themselves, but otherwise,
it’s probably a mistake.
The usual convention for Object.clone()
according to Oracle’s Javadoc is:
-
x.clone() != x
-
x.clone().getClass() == x.getClass()
-
x.clone().equals(x)
Obtaining the object that will be returned by calling super.clone()
helps to satisfy those invariants:
-
super.clone()
returns a new object instance
-
super.clone()
returns an object of the same type as the one clone()
was called on
-
Object.clone()
performs a shallow copy of the object’s state.
How to fix it
Ensure that the clone()
method calls super.clone()
and implement Cloneable
in the class or remove the clone
method.
Code examples
Noncompliant code example
class BaseClass { // Noncompliant - should implement Cloneable
@Override
public Object clone() throws CloneNotSupportedException { // Noncompliant - should return the super.clone() instance
return new BaseClass();
}
}
class DerivedClass extends BaseClass implements Cloneable {
/* Does not override clone() */
public void sayHello() {
System.out.println("Hello, world!");
}
}
class Application {
public static void main(String[] args) throws Exception {
DerivedClass instance = new DerivedClass();
((DerivedClass) instance.clone()).sayHello(); // Throws a ClassCastException because invariant #2 is violated
}
}
Compliant solution
class BaseClass implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException { // Compliant
return super.clone();
}
}
class DerivedClass extends BaseClass implements Cloneable {
/* Does not override clone() */
public void sayHello() {
System.out.println("Hello, world!");
}
}
class Application {
public static void main(String[] args) throws Exception {
DerivedClass instance = new DerivedClass();
((DerivedClass) instance.clone()).sayHello(); // Displays "Hello, world!" as expected. Invariant #2 is satisfied
}
}
Resources