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="045ca2a9-a7b6-4c9a-819d-f91ad4270bf9"><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