Copy constructors
Defensive copying
Factory methods
clone.
clone is very tricky to implement correctly in all circumstances,
nearly to the point of being pathologicalclone, and are much
easier to implementclone, 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 colour, Date bestBeforeDate) { super(); this.colour = colour; //defensive copy needed for this mutable object this.bestBeforeDate = new Date(bestBeforeDate.getTime()); } public abstract void ripen(); public String getColour() { return colour; } public Date getBestBeforeDate() { //return defensive copy of this mutable object return new Date(bestBeforeDate.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.bestBeforeDate = new Date(this.bestBeforeDate.getTime()); return result; } // PRIVATE /** Strings are always immutable. */ private String colour; /** * In new code, you should use LocalDate, not java.util.Date! * Here, java.util.Date is used only to make a point regarding mutable fields. * * 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 bestBeforeDate; }Here is the subclass, with its
clone method disabled.
import java.util.Date; public final class Apple extends Fruit { public Apple(String colour, Date bestBeforeDate) { super(colour, bestBeforeDate); } 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(); } }