Source of CheckCloneable.java


  1: //: appendixa:CheckCloneable.java
  2: // From 'Thinking in Java, 2nd ed.' by Bruce Eckel
  3: // www.BruceEckel.com. See copyright notice in CopyRight.txt.
  4: // Checking to see if a reference can be cloned.

  6: // Can't clone this because it doesn't
  7: // override clone():
  8: class Ordinary {}

 10: // Overrides clone, but doesn't implement
 11: // Cloneable:
 12: class WrongClone extends Ordinary {
 13:   public Object clone()
 14:       throws CloneNotSupportedException {
 15:     return super.clone(); // Throws exception
 16:   }
 17: }

 19: // Does all the right things for cloning:
 20: class IsCloneable extends Ordinary 
 21: implements Cloneable {
 22:   public Object clone() 
 23:       throws CloneNotSupportedException {
 24:     return super.clone();
 25:   }
 26: }

 28: // Turn off cloning by throwing the exception:
 29: class NoMore extends IsCloneable {
 30:   public Object clone() 
 31:       throws CloneNotSupportedException {
 32:     throw new CloneNotSupportedException();
 33:   }
 34: }

 36: class TryMore extends NoMore {
 37:   public Object clone() 
 38:       throws CloneNotSupportedException {
 39:     // Calls NoMore.clone(), throws exception:
 40:     return super.clone();
 41:   }
 42: }

 44: class BackOn extends NoMore {
 45:   private BackOn duplicate(BackOn b) {
 46:     // Somehow make a copy of b
 47:     // and return that copy. This is a dummy
 48:     // copy, just to make the point:
 49:     return new BackOn();
 50:   }
 51:   public Object clone() {
 52:     // Doesn't call NoMore.clone():
 53:     return duplicate(this);
 54:   }
 55: }

 57: // Can't inherit from this, so can't override
 58: // the clone method like in BackOn:
 59: final class ReallyNoMore extends NoMore {}

 61: public class CheckCloneable {
 62:   static Ordinary tryToClone(Ordinary ord) {
 63:     String id = ord.getClass().getName();
 64:     Ordinary x = null;
 65:     if(ord instanceof Cloneable) {
 66:       try {
 67:         System.out.println("Attempting " + id);
 68:         x = (Ordinary)((IsCloneable)ord).clone();
 69:         System.out.println("Cloned " + id);
 70:       } catch(CloneNotSupportedException e) {
 71:         System.err.println("Could not clone "+id);
 72:       }
 73:     }
 74:     return x;
 75:   }
 76:   public static void main(String[] args) {
 77:     // Upcasting:
 78:     Ordinary[] ord = { 
 79:       new IsCloneable(),
 80:       new WrongClone(),
 81:       new NoMore(),
 82:       new TryMore(),
 83:       new BackOn(),
 84:       new ReallyNoMore(),
 85:     };
 86:     Ordinary x = new Ordinary();
 87:     // This won't compile, since clone() is
 88:     // protected in Object:
 89:     //! x = (Ordinary)x.clone();
 90:     // tryToClone() checks first to see if
 91:     // a class implements Cloneable:
 92:     for(int i = 0; i < ord.length; i++)
 93:       tryToClone(ord[i]);
 94:   }
 95: } ///:~