[3]Cloneable should have been spelled Clonable, but the misspelling was
realized too late to be fixed.
The clone method implemented by the Object class, which performs a simple clone by copying
all fields of the original object to the new object. This method works for many classes but may need to
be supplemented by an overriding method.
•
The CloneNotSupportedException, which can be used to signal that a class's clone method
shouldn't have been invoked.
•
A given class can have one of four different attitudes toward clone:
Support clone. Such a class implements Cloneable and declares its clone method to throw no
exceptions.
•
Conditionally support clone. Such a class might be a collection class that can be cloned in principle
but cannot successfully be cloned unless its contents can be cloned. This kind of class will implement
Cloneable, but will let its clone method pass through any CloneNotSupportedException
it may receive from other objects it tries to clone. Or a class may have the ability to be cloned itself
but not require that all subclasses also have the ability to be cloned.
•
Allow subclasses to support clone but don't publicly support it. Such a class doesn't implement
Cloneable, but if the default implementation of clone isn't correct, the class provides a protected
clone implementation that clones its fields correctly.
•
Forbid clone. Such a class does not implement Cloneable and provides a clone method that
always throws CloneNotSupportedException.
•
Object.clone checks whether the object on which it was invoked implements the Cloneable interface
and throws CloneNotSupportedException if it does not. Otherwise, Object.clone creates a new
object of exactly the same type as the original object on which clone is invoked and initializes the fields of
the new, cloned object to have the same values as the fields of the original object. When Object.clone is
finished, it returns a reference to the new object.
The simplest way to make a class that can be cloned is to declare that it implements the Cloneable
interface, and override the clone method, redeclaring it to be public:
public class MyClass extends HerClass implements Cloneable {
public MyClass clone()
throws CloneNotSupportedException {
return (MyClass) super.clone();
}
// ...
}
Any other code can now make a clone of a MyClass object. In this simple case, all fields of MyClass will
be assigned by Object.clone into the new object that is returned. Note that the overriding implementation
declares that it returns an instance of MyClass, not Object, utilizing the ability to specify a covariant
return typethis saves the calling code from having to supply a cast, but we have to supply it internally when
returning the value from super.clone().
The clone method in Object has a throwsCloneNotSupportedException declaration. This
means a class can declare that it can be cloned, but a subclass can decide that it can't be cloned. Such a
subclass would implement the Cloneable interface because it extends a class that does so, but the subclass
could not, in fact, be cloned. The extended class would make this known by overriding clone to always
throw CloneNotSupportedException and documenting that it does so. Be carefulthis means that you
cannot determine whether a class can be cloned by a run time check to see whether the class implements
Cloneable. Some classes that can't be cloned will be forced to signal this condition by throwing an
exception.