问题
The Java specification for the java.lang.Cloneable
interface defines itself as signifying that any object that extends it also has implemented the clone()
method that rests dormant within java.lang.Object
. Specifically, it says that:
A class implements the
Cloneable
interface to indicate to thejava.lang.Object#clone()
method that it is legal for that method to make a field-for-field copy of instances of that class.
To me, this means that it should be assumed that every class that extends Cloneable
therefore also has a public Object clone()
method within it. This makes it easy to assume that the following is a valid method:
public static makeACloneFrom(Cloneable c)
{
return c.clone();
}
however, this is not the case, as the entirety of the Cloneable
source code (sans javadoc) is simply
package java.lang;
public interface Cloneable {
}
Which means that Cloneable#clone()
does not exist (and trying to compile the example method above throws a compile-time error saying something like "cannot find symbol: method clone()
"). Shouldn't the source code of Cloneable
contain something to the effect of public Cloneable clone();
?
Why aren't we allowed to assume that a class that implements Cloneable
has a public Cloneable clone()
method?
回答1:
Because it's a poorly-designed interface.
From Effective Java (sorry, Google Books does not have a preview for the 2nd edition):
Item 11: Override
clone
judiciouslyThe
Cloneable
interface was intended as a mixin interface (Item 18) for objects to advertise that they permit cloning. Unfortunately, it fails to serve this purpose. Its primary flaw is that it lacks aclone
method, andObject
'sclone
method is protected. You cannot, with resorting to reflection (Item 53), invoke theclone
method on an object merely because it implementsCloneable
. Even a reflective invocation may fail, as there is no guarantee that the object has an accessibleclone
method.
回答2:
Ugh. clone
and Cloneable
are broken, terribly designed, and shouldn't be used in new code. (See Effective Java item 11.)
The reason for this particular thing is that Cloneable
is a confusingly implemented, magical interface such that the mere act of implementing Cloneable
changes the behavior of Object.clone
with reflection. Effective Java says:
...if a class implements
Cloneable
,Object
’sclone
method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException. This is a highly atypical use of interfaces and not one to be emulated...
来源:https://stackoverflow.com/questions/9981796/why-does-java-lang-cloneable-not-override-the-clone-method-in-java-lang-object