Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Parasoft Jtest 2022.2

This is a stub. It needs an example of an error caused by using the base class's object where the subclass's object was expected. It should not produce a RuntimeException (ClassCastException) to qualify.

When 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 typeclass.

The Java API [API 2013] for the clone() method [API 2006] 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 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
bgColor#FFcccc
class Base implements Cloneable {
  public Object clone() throws CloneNotSupportedException {
    return new Base();	 
  }
  protected void doLogic() {
    System.out.println("Superclass doLogic");
  }
}

class Derived extends Base {
  public Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
  protected void doLogic() {
    System.out.println("Subclass doLogic");
  }
  public static void main(String[] args) {
    Derived dev = new Derived();
    try {
      Base 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
bgColor#ccccff
class Base implements Cloneable {
  public Object clone() throws CloneNotSupportedException {
    return super.clone();	 
  }
  protected void doLogic() {
    System.out.println("Superclass doLogic");
  }
}

class Derived extends Base {
  public Object clone() throws CloneNotSupportedException {
    return super.clone();
  }
  protected void doLogic() {
    System.out.println("Subclass doLogic");
  }
  public static void main(String[] args) {
    Derived dev = new Derived();
    try {
      // Has type Derived, as expected
      Base devClone = (Base)dev.clone(); // has type Derived, as expected
      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.

Guideline

Severity

Likelihood

Remediation Cost

Priority

Level

MET53-JG

medium

probable

low

P12

L1

Automated Detection

...

.

Automated Detection

ToolVersionCheckerDescription
Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.MET53.SCLONECall 'super.clone()' in all 'clone()' methods
SonarQube
Include Page
SonarQube_V
SonarQube_V
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 methodsImage Added Image Added Image Added