`
leonzhx
  • 浏览: 794127 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Avoid clone

阅读更多

Avoid implementing clone.

  • clone is very tricky to implement correctly in all circumstances, nearly to the point of being pathological
  • the importance of copying objects will always remain, since object fields often need to be defensively copied
  • copy constructors and static factory methods provide an alternative to clone, and are much easier to implement

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();
  }
} 

 

This article originates from http://www.javapractices.com/topic/TopicAction.do;jsessionid=F5C214E7452424EA265D4DD5A493BF2B?Id=71

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics