Mega Code Archive

 
Categories / Java / Class
 

Checking to see if a reference can be cloned

// : appendixa:CheckCloneable.java // Checking to see if a reference can be cloned. // From 'Thinking in Java, 3rd ed.' (c) Bruce Eckel 2002 // www.BruceEckel.com. See copyright notice in CopyRight.txt. // Can't clone this because it doesn't override clone(): class Ordinary { } // Overrides clone, but doesn't implement Cloneable: class WrongClone extends Ordinary {   public Object clone() throws CloneNotSupportedException {     return super.clone(); // Throws exception   } } // Does all the right things for cloning: class IsCloneable extends Ordinary implements Cloneable {   public Object clone() throws CloneNotSupportedException {     return super.clone();   } } // Turn off cloning by throwing the exception: class NoMore extends IsCloneable {   public Object clone() throws CloneNotSupportedException {     throw new CloneNotSupportedException();   } } class TryMore extends NoMore {   public Object clone() throws CloneNotSupportedException {     // Calls NoMore.clone(), throws exception:     return super.clone();   } } class BackOn extends NoMore {   private BackOn duplicate(BackOn b) {     // Somehow make a copy of b and return that copy.     // This is a dummy copy, just to make the point:     return new BackOn();   }   public Object clone() {     // Doesn't call NoMore.clone():     return duplicate(this);   } } // You can't inherit from this, so you can't override // the clone method as you can in BackOn: final class ReallyNoMore extends NoMore { } public class CheckCloneable {   public static Ordinary tryToClone(Ordinary ord) {     String id = ord.getClass().getName();     System.out.println("Attempting " + id);     Ordinary x = null;     if (ord instanceof Cloneable) {       try {         x = (Ordinary) ((IsCloneable) ord).clone();         System.out.println("Cloned " + id);       } catch (CloneNotSupportedException e) {         System.err.println("Could not clone " + id);       }     } else {       System.out.println("Doesn't implement Cloneable");     }     return x;   }   public static void main(String[] args) {     // Upcasting:     Ordinary[] ord = { new IsCloneable(), new WrongClone(), new NoMore(),         new TryMore(), new BackOn(), new ReallyNoMore(), };     Ordinary x = new Ordinary();     // This won't compile; clone() is protected in Object:     //! x = (Ordinary)x.clone();     // Checks first to see if a class implements Cloneable:     for (int i = 0; i < ord.length; i++)       tryToClone(ord[i]);   } } ///:~