This is a stub. It needs an example of an error caused due to using the Base class's object where the subclass's object was expected. It should not produce a RuntimeException (ClassCastException) to qualify.
When a non-final class defines a clone() method that does not call super.clone(), cloning a subtype will produce an object of the wrong type.
| Wiki Markup |
|---|
The Java API for the {{clone()}} method \[[API 2006|AA. References#API 06]\] says: |
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().
Noncompliant Code Example
In this noncompliant code example, the clone() method in the class Base does not call super.clone(). Hence, the object devClone ends up being of type Base instead of Derived, with resulting incorrect application of the doLogic() method.
| Code Block | ||
|---|---|---|
| ||
class Base implements Cloneable {
public Object clone() throws CloneNotSupportedException {
return new Base();
}
protected static void doLogic() {
System.out.println("Superclass doLogic");
}
}
class Subclass1Derived extends Base {
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
protected static void doLogic() {
System.out.println("Subclass doLogic");
}
public static void main(String[] args) {
Subclass1Derived sdev = new Subclass1Derived();
try {
Object scdevClone = sdev.clone(); // has get'stype Base obj instead of Derived
devClone.doLogic(); // prints "Superclass doLogic" instead of subclass'
"Subclass doLogic"
} catch (CloneNotSupportedException e) { /* ... */ }
}
}
|
Compliant Solution
This compliant solution correctly calls super.clone() in the Base class's clone() method.
| Code Block | ||
|---|---|---|
| ||
class Base implements Cloneable { public Object clone() throws CloneNotSupportedException { return super.clone(); } protected static void doLogic() { System.out.println(sc.getClass().hashCode()); // a possible mistake"Superclass doLogic"); } } class Derived extends Base { public Object clone() throws CloneNotSupportedException { return super.clone(); } protected static void doLogic() { System.out.println("Subclass doLogic"); } public static void main(String[] args) { Derived dev = new Derived(); try { Object devClone = dev.clone(); // ((Subclass1)sc) has type Derived, as expected devClone.doLogic(); // prints Produces"Subclass ClassCastExceptiondoLogic", disqualifiedas expected } catch (CloneNotSupportedException e) { /* ... */ } } } |
Risk Assessment
Failing to call super.clone() may result in a cloned object having the wrong type, with resulting unexpected or incorrect results when it is used.
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
|---|---|---|---|---|---|
MET55-J | medium | probable | low | P12 | L1 |
Automated Detection
Automated detection is straightforward.
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="f804f6d7-7190-4061-bb39-a6f200abe618"><ac:plain-text-body><![CDATA[ | [[API 2006 | AA. References#API 06]] | [Class Object | http://java.sun.com/javase/6/docs/api/java/lang/Object.html] | ]]></ac:plain-text-body></ac:structured-macro> |
...
MET15-J. Do not use deprecated or obsolete classes or methods 05. Methods (MET) MET17-J. Do not increase the accessibility of overridden or hidden methods