OnJava8-Examples/references/CheckCloneable.java
2015-05-05 11:20:13 -07:00

91 lines
2.4 KiB
Java

//: references/CheckCloneable.java
// Checking to see if a reference can be cloned.
// Can't clone this because it doesn't override clone():
class Ordinary {}
// Overrides clone, but doesn't implement Cloneable:
class WrongClone extends Ordinary {
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone(); // Throws exception
}
}
// Does all the right things for cloning:
class IsCloneable extends Ordinary implements Cloneable {
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// Turn off cloning by throwing the exception:
class NoMore extends IsCloneable {
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
class TryMore extends NoMore {
@Override
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();
}
@Override
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]);
}
} ///:~