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 Cloning a subclass a nonfinal class that defines a clone() method that does not fails to call super.clone(), cloning a subtype will produce an object of the wrong type.unmigrated-wiki-markupclass.
The Java API [API 2013] 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 fails to 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 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 { ObjectBase devClone = (Base)dev.clone(); // hasHas type Base instead of Derived devClone.doLogic(); // printsPrints "Superclass doLogic" instead of "Subclass doLogic" } catch (CloneNotSupportedException e) { /* ... */ } } } |
Consequently, the object devClone ends up being of type Base instead of Derived, and the doLogic() method is incorrectly applied.
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("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(); // hasHas type Derived, as expected Base devClone = (Base)dev.clone(); devClone.doLogic(); // printsPrints "Subclass doLogic", as expected } catch (CloneNotSupportedException e) { /* ... */ } } } |
...
Applicability
Failing to call super.clone() may result in cause a cloned object having to have the wrong type, with resulting unexpected or incorrect results when it is used.
...
Automated Detection
| Tool |
|---|
| Version |
|---|
| Checker |
|---|
| Description |
|---|
| CodeSonar |
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="3b168ed7-6814-41c0-8a4d-d5e7bf50f076"><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> |
| JAVA.CLASS.CLONE.CCSM JAVA.CLASS.MCS | Clone call to super is missing Missing call to super | |||||||
| Parasoft Jtest |
| CERT.MET53.SCLONE | Call 'super.clone()' in all 'clone()' methods | ||||||
| SonarQube |
| S1182 |
Bibliography
...
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