Versions Compared

Key

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

When Cloning a subclass a nonfinal class that defines a clone() method that fails to call super.clone(), cloning a subclass of this class will produce an object of the wrong class.

The Java API [API 20112013] for the clone() method 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 fails to call super.clone():

...

Consequently, the object devClone ends up being of type Base instead of Derived and , 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();  // Prints "Subclass doLogic", as expected
    } catch (CloneNotSupportedException e) { /* ... */ }
  }
}

Applicability

Failing to call super.clone() may cause a cloned object to have the wrong type, with unexpected or incorrect results when it is used.

Bibliography

 

...