Avoid clone

Avoid implementing clone. If you need to extend a superclass that implements clone, then your subclass must implement clone as well. The quickest solution is for your subclass to simply throw an exception.

Example

This example shows a superclass with a typical implementation of clone, and a subclass which has disabled its clone method.


import java.util.Date;

public abstract class Fruit implements Cloneable {

  public Fruit(String aColour, Date aBestBeforeDate) {
    super();
    fColour = aColour;
    //defensive copy needed for this mutable object
    fBestBeforeDate = new Date(aBestBeforeDate.getTime());
  }

  public abstract void ripen();

  public String getColour() {
    return fColour;
  }

  public Date getBestBeforeDate() {
    //return defensive copy of this mutable object
    return new Date(fBestBeforeDate.getTime());
  }

  /**
  * Implement clone as follows
  * <ul>
  * <li>the class declaration "implements Cloneable" (not needed if already
  * declared in superclass)
  * <li>declare clone method as public
  * <li>if the class is final, clone does not need to throw CloneNotSupportedException
  * <li>call super.clone and cast to this class
  * <li>as in defensive copying, ensure each mutable field has an independent copy
  * constructed, to avoid sharing internal state between objects
  * </ul>
  */
  @Override public Object clone() throws CloneNotSupportedException {
    //get initial bit-by-bit copy, which handles all immutable fields
    Fruit result = (Fruit)super.clone();

    //mutable fields need to be made independent of this object, for reasons
    //similar to those for defensive copies - to prevent unwanted access to
    //this object's internal state
    result.fBestBeforeDate = new Date(this.fBestBeforeDate.getTime());

    return result;
  }

  // PRIVATE

  /**
  * Strings are always immutable.
  */
  private String fColour;

  /**
  * Date is a mutable object. In this class, this object field is to be treated
  * as belonging entirely to this class, and no user of this class is
  * to be able to directly access and change this field's state.
  */
  private Date fBestBeforeDate;
} 

Here is the subclass, with its clone method disabled.

import java.util.Date;

public final class Apple extends Fruit {

  public Apple(String aColour, Date aBestBeforeDate) {
    super(aColour, aBestBeforeDate);
  }

  public void ripen() {
    //empty implementation of abstract method
  }

  /**
  * The Apple subclass does not support clone.
  */
  @Override public final Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
  }
} 



See Also :
Copy constructors
Defensive copying
Factory methods
Would you use this technique?
Yes   No   Undecided   
© 2014 Hirondelle Systems | Source Code | Contact | License | RSS
Individual code snippets can be used under this BSD license - Last updated on September 21, 2013.
Over 2,000,000 unique IPs last year - Built with WEB4J.
- In Memoriam : Bill Dirani -