为了账号安全,请及时绑定邮箱和手机立即绑定

如何正确覆盖克隆方法?

如何正确覆盖克隆方法?

长风秋雁 2019-07-06 16:20:15
如何正确覆盖克隆方法?我需要在没有超类的对象中实现深度克隆。处理检查结果的最佳方法是什么?CloneNotSupportedException由超类引发的Object)?一位同事建议我以下方式处理这件事:@Overridepublic MyObject clone(){     MyObject foo;     try     {         foo = (MyObject) super.clone();     }     catch (CloneNotSupportedException e)     {         throw new Error();     }     // Deep clone member fields here     return foo;}对我来说,这似乎是一个很好的解决方案,但我想把它扔给StackOverflow社区,看看是否还有其他我可以包含的见解。谢谢!
查看完整描述

3 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

你一定要用clone?大多数人都认为Java的clone都坏了。

乔希·布洛赫谈设计复制构造器与克隆

如果你读过我书中关于克隆的文章,尤其是你读过的话,你就会知道我认为clone是深深的破碎。[.]很遗憾Cloneable是坏的,但它会发生。

你可以在他的书中读到关于这个主题的更多讨论。有效Java第2版,第11项:覆盖clone明智地..他建议使用复制构造函数或复制工厂。

他接着写了几页,如果你觉得必须的话,你应该如何实现。clone..但他最后说:

这些复杂的事情真的有必要吗?很少。如果扩展实现Cloneable,您别无选择,只能实现一个良好的行为。clone方法。否则,您最好提供另一种对象复制方法,或者干脆不提供此功能。.

重点是他的,不是我的。


因为你清楚地表明你别无选择,只能实现clone,在这种情况下,您可以这样做:确保MyObject extends java.lang.Object implements java.lang.Cloneable..如果是这样的话,你可以保证绝不可能抓到CloneNotSupportedException..投掷AssertionError正如一些人所建议的,似乎是合理的,但您也可以添加一个注释,解释为什么永远不会输入CATCH块。在这种情况下.


或者,正如其他人所建议的,您也许可以实现clone不打电话super.clone.


查看完整回答
反对 回复 2019-07-06
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

有两种情况CloneNotSupportedException将被抛出:

  1. 要克隆的类没有实现。

    Cloneable

    (假设实际的克隆最终符合

    Object

    如果要在实现中编写此方法的类

    Cloneable

    ,这种情况永远不会发生(因为任何子类都会适当地继承它)。
  2. 异常由实现显式抛出这是在超类为

    Cloneable.

后一种情况不能发生在您的类中(因为您正在直接调用try块,即使从子类调用super.clone())而前者不应该因为你的课清楚地应该实现Cloneable.

基本上,您应该确定地记录错误,但是在这个特定的例子中,只有当您弄糟了类的定义时,它才会发生。因此,将其视为NullPointerException(或类似的)-如果您的代码是功能性的,就永远不会抛出它。


在其他情况下,您需要为这种情况做好准备-不能保证给定的对象可克隆,因此当捕获异常时,应根据此条件采取适当的操作(继续使用现有对象,采取替代的克隆策略,例如序列化反序列化,抛出IllegalParameterException如果您的方法需要可克隆的参数,等等)。

编辑:虽然总的来说,我应该指出,是的,clone()确实很难正确地实现,调用者也很难知道返回值是否会是他们想要的,当您考虑深的和浅的克隆时,更是如此。通常情况下,最好是完全避免整件事,并使用另一种机制。


查看完整回答
反对 回复 2019-07-06
  • 3 回答
  • 0 关注
  • 333 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号