111 lines
2.7 KiB
Java
111 lines
2.7 KiB
Java
//: references/CheckCloneable.java
|
|
// Check to see if a reference can be cloned.
|
|
|
|
// Can't clone this -- doesn't override clone():
|
|
class Ordinary {}
|
|
|
|
// Overrides clone, 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. A dummy copy, just to make a 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 clone() 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(Ordinary ord1 : ord) {
|
|
tryToClone(ord1);
|
|
}
|
|
}
|
|
} /* Output:
|
|
Attempting IsCloneable
|
|
Cloned IsCloneable
|
|
Attempting WrongClone
|
|
Doesn't implement Cloneable
|
|
Attempting NoMore
|
|
Could not clone NoMore
|
|
Attempting TryMore
|
|
Could not clone TryMore
|
|
Attempting BackOn
|
|
Cloned BackOn
|
|
Attempting ReallyNoMore
|
|
Could not clone ReallyNoMore
|
|
*///:~
|