Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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 (except Object) obey this convention, it will be the case that x.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
bgColor#FFcccc
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
bgColor#ccccff

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