class Ordinary
class WrongClone extends Ordinary
class IsCloneable extends Ordinary
class NoMore extends IsCloneable
class TryMore extends NoMore
class BackOn extends NoMore
public class CheckCloneable
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: } ///:~