美文网首页
Effective Java 第11条: 谨慎的覆盖clone

Effective Java 第11条: 谨慎的覆盖clone

作者: linyk3 | 来源:发表于2019-01-03 15:32 被阅读0次

Cloneable 接口的目的是作为对象的一个 mixin 接口, 表明这样的对象允许克隆.
遗憾的是,因为Object 对象的clone 方法是受保护的, 一个对象仅仅实现了Cloneable, 但能直接调用clone, 所以导致Cloneable 没有成功达到目的.

如果一个类实现了Cloneable, Object 的 clone 方法就返回该对象的逐域拷贝, 否则就会抛出 CloneNotSupportException 异常.

Clone 方法的通用约定是非常弱的:
创建和返回该对象的一个拷贝,这个拷贝的精确含义取决于该对象的类. 通常情况下满足,但是不强制要求一定要满足:
x.clone() != x, x.clone().getClass() == x.getClass(), x.clone.equals(x)

对于实现了 Cloneable 的类, 我们总是期望它能提供一个功能适当的公有的clone的方法.

实际上, clone 方法就是另一个构造器; 必须确保它不会伤害到原始的对象, 并确保正确地创建被克隆对象中的约束条件.

clone 架构与引用可变对象的final域的正常使用是不兼容的.

简而言之, 所有实现了 Cloneable 接口的类都应该用一个公有的方法覆盖 clone.
此公有的clone 方法首先调用 super.clone, 然后修正任何需要修正的域.一般情况下,这意味着要拷贝任何包含内部"深层结构"的可变对象, 并用指向新对象的引用来代替原来指向这些对象的引用. 如果该类只包含基本类型的域,或者指向不可变对象的引用,那么多半情况下是没有域需要修正的.

另一个实现对象拷贝的好办法就是提供一个拷贝构造器,或拷贝工厂:

  • 拷贝构造器: public Yum( Yum yum)
  • 拷贝工厂: public static Yum nerInstance(Yum yum)

拷贝构造器和拷贝工厂,都比Cloneable/clone方法具有更多的优势:

  • 不依赖于某一种有风险的,语言之外的对象创建机制
  • 不要求遵守尚未制定好的文档规范
  • 不会与final 域的正常使用发生冲突
  • 不会抛出不必要的首检异常
  • 不需要进行类型转换

Cloneable 具有很多的限制,所以其他的接口都不应该扩展(extend)这个接口, 为了继承而设计的类也不应该实现(implement)这个接口.

相关文章

网友评论

      本文标题:Effective Java 第11条: 谨慎的覆盖clone

      本文链接:https://www.haomeiwen.com/subject/hdbfrqtx.html