Why is the clone() method protected in java.lang.Object?
The Clonable interface is just a marker saying the class can support clone. The method is protected because you shouldn't call it on object, you can (and should) override it as public.
From Sun:
In class Object, the clone() method is declared protected. If all you do is implement Cloneable, only subclasses and members of the same package will be able to invoke clone() on the object. To enable any class in any package to access the clone() method, you'll have to override it and declare it public, as is done below. (When you override a method, you can make it less private, but not more private. Here, the protected clone() method in Object is being overridden as a public method.)
clone
is protected because it is something that ought to be overridden so that it is specific to the current class. While it would be possible to create a public clone
method that would clone any object at all this would not be as good as a method written specifically for the class that needs it.
The fact that clone is protected is extremely dubious - as is the fact that the clone
method is not declared in the Cloneable
interface.
It makes the method pretty useless for taking copies of data because you cannot say:
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
I think that the design of Cloneable
is now largely regarded as a mistake (citation below). I would normally want to be able to make implementations of an interface Cloneable
but not necessarily make the interface Cloneable
(similar to the use of Serializable
). This cannot be done without reflection:
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Citation From Josh Bloch's Effective Java:
"The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be emulated ... In order for implementing the interface to have any effect on a class, it and all of its superclasses must obey a fairly complex, unenforceable and largely undocumented protocol"