为什么在java.lang.Object中保护clone()方法?

Ale*_* N. 105 java oop clone

clone()定义为受保护的具体原因是java.lang.Object什么?

oxb*_*kes 104

克隆被保护的事实是非常可疑的 - 因为该clone方法未在Cloneable接口中声明.

这使得该方法对于获取数据副本毫无用处,因为您无法说:

if(a instanceof Cloneable) {
    copy = ((Cloneable) a).clone();
}
Run Code Online (Sandbox Code Playgroud)

我认为,设计Cloneable是现在很大程度上被视为一个错误(以下引文).我通常希望能够实现接口Cloneable不一定要创建接口Cloneable(类似于使用Serializable).没有反思就无法做到这一点:

ISomething i = ...
if (i instanceof Cloneable) {
   //DAMN! I Need to know about ISomethingImpl! Unless...
   copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Run Code Online (Sandbox Code Playgroud)

来自Josh Bloch的Effective Java的引用:
"Cloneable接口旨在作为一个mixin接口,用于对象宣传它们允许克隆.不幸的是它无法达到此目的......这是一种非常非典型的接口使用,而不是一个模拟的接口...为了实现接口对类产生任何影响,它和它的所有超类必须服从一个相当复杂,不可执行且基本上没有文档的协议 "

  • @Kevin - **Josh Bloch的**有效Java pp45.*"Cloneable接口旨在作为一个mixin接口,用于宣传他们允许克隆的对象.不幸的是,它无法满足此目的"* (6认同)
  • 引文添加到主要条目 (3认同)
  • 如果对象不是Cloneable,则Object的clone()将抛出CloneNotSupportedException.因此,如果要调用super.clone()(导致调用Object.clone()),则需要Cloneable.我没有看到如何在不实现Serializable的情况下序列化对象. (2认同)

Bil*_*l K 27

Clonable接口只是一个标记,表示该类可以支持克隆.该方法受到保护,因为您不应该在对象上调用它,您可以(并且应该)将其覆盖为public.

来自Sun:

在Object类中,clone()方法被声明为protected.如果你所做的只是实现Cloneable,那么只有子类和同一个包的成员才能在对象上调用clone().要使任何包中的任何类能够访问clone()方法,您必须覆盖它并将其公开,如下所示.(当你重写一个方法时,你可以减少它的私有性,但不能更私密.这里,Object中的protected clone()方法被重写为公共方法.)

  • 你不能克隆任何没有实现Cloneable接口的东西,只是因为某些东西实现了Cloneable接口并不意味着你可以克隆它. (4认同)
  • 你无法克隆任何没有实现Clonable接口的东西 - 它是一个标记,上面写着"这个类可以正确克隆" - 与Serializable接口非常相似.顺便说一句,有一种方法可以通过序列化来克隆类,这种方法效果很好 - 谷歌类似于"java序列化克隆",你可能会找到一些方法来获得对象的深层副本. (3认同)

And*_*are 7

clone是受保护的,因为它应该被覆盖,以便它特定于当前类.虽然可以创建一个clone克隆任何对象的公共方法,但这不如专门针对需要它的类编写的方法那么好.

  • 它受到保护,所以你不要在对象中使用它(它只会抛出异常).他们希望你在课堂​​上覆盖它,然后你公开它.(也在下面回答了几次) (3认同)