91 lines
2.4 KiB
Java
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]);
|
|
}
|
|
} ///:~
|