WEB4J - Minimalist Java Web Application Framework

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   
Add your comment to this Topic :

© 2008 Hirondelle Systems | Source Code | Contact | License | Quotes | RSS
Individual code snippets can be used under this license - Last updated on September 6, 2008.
Over 98,000 visits last month - Built with WEB4J.
- In Memoriam : Bill Dirani -