Item 13: Override clone judiciously

笔记

  • The Cloneable interface was intended as a mixin interface (Item 20) for classes to advertise that they permit cloning.
    没有实现Cloneable接口的对象,在调用clone方法时会抛异常。所以要使用clone方法,需做两件事情:1. 实现Cloneable接口;2.覆写clone方法,修改访问控制为public,因Object自带的方法是protected权限。

  • It determines the behavior of Object’s protected clone implementation: if a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException.
    克隆的方式是一个个字段的拷贝。

  • in practice, a class implementing Cloneable is expected to provide a properly functioning public clone method.
    实现public权限的clone方法以供外界使用。

  • The resulting mechanism is fragile, dangerous, and extralinguistic: it creates objects without calling a constructor.
    在构造函数里实现的操作会被略过。

  • The general contract for the clone method is weak.

  • if a class’s clone method returns an instance that is not obtained by calling super.clone but by calling a constructor, the compiler won’t complain, but if a subclass of that class calls super.clone, the resulting object will have the wrong class, preventing the subclass from clone method from working properly.
    clone方法不要调用构造方法,如果它有子类的话。

  • by calling super.clone(Object.clone), the object you get back will be a fully functional replica of the original. Any fields declared in your class will have values identical to those of the original.
    Object.clone方法是浅复制。如果属性是引用类型,则新老对象都是引用的同一个对象。

  • Java supports covariant return types. In other words, an overriding method’s return type can be a subclass of the overridden method’s return type.
    java支持协变返回类型。

  • If an object contains fields that refer to mutable objects, the simple clone implementation shown earlier can be disastrous.
    如果属性是引用可变对象,默认的浅复制Object.clone()实现会引入问题。

  • In effect, the clone method functions as a constructor; you must ensure that it does no harm to the original object and that it properly establishes invariants on the clone.
    clone方法不能影响原来的对象。

  • the Cloneable architecture is incompatible with normal use of final fields referring to mutable objects,
    except in cases where the mutable objects may be safely shared between an object and its clone.
    如果字段是final属性的可变对象,clone就不起作用了,除非这个字段是对象间共享的。

  • A final approach to cloning complex mutable objects is to call super.clone, set all of the fields in the resulting object to their initial state, and then call higherlevel methods to regenerate the state of the original object.
    先初始化,然后再复制状态。

  • Like a constructor, a clone method must never invoke an overridable method on the clone under construction (Item 19). If clone invokes a method that is overridden in a subclass, this method will execute before the subclass has had a chance to fix its state in the clone, quite possibly leading to corruption in the clone and the original.
    clone方法里不能调用覆写的方法,有风险。

  • Public clone methods should omit the throws clause, as methods that don’t throw checked exceptions are easier to use (Item 71).
    把麻烦留给自己。

  • You have two choices when designing a class for inheritance (Item 19), but whichever one you choose, the class should not implement Cloneable.
    继承链中间的类不要实现clone方法。

  • Object’s clone method is not synchronized, so even if its implementation is otherwise satisfactory, you may have to write a synchronized clone method that returns super.clone().
    做好线程保护。

  • all classes that implement Cloneable should override clone with a public method whose return type is the class itself. This method should first call super.clone, then fix any fields that need fixing.

  • A better approach to object copying is to provide a copy constructor or copy factory.

  • The copy constructor approach and its static factory variant have many advantages over Cloneable/clone: they don’t rely on a risk-prone extralinguistic object creation mechanism; they don’t demand unenforceable adherence to thinly documented conventions; they don’t conflict with the proper use of final fields; they don’t throw unnecessary checked exceptions; and they don’t require casts.
    还是用copy构造函数或者静态方法来实现clone效果更好。

  • Given all the problems associated with Cloneable, new interfaces should not extend it, and new extendable classes should not implement it.

  • While it’s less harmful for final classes to implement Cloneable, this should be viewed as a performance optimization, reserved for the rare cases where it is justified (Item 67).
    final类可以用,在对性能有要求的地方。

  • As a rule, copy functionality is best provided by constructors or factories. A notable exception to this rule is arrays, which are best copied with the clone method.
    array还是要用clone。其他的用构造函数和工厂方法。

理解与思考

  • 一般是clone值对象。构成复杂的对象最好不用clone,容易出错。
  • 实现clone方法的一般步骤是:先调用super.clone复制对象,然后去修正对象的状态。
  • 在涉及继承和线程安全的时候,需慎重考虑。

实践

你可能感兴趣的:(Item 13: Override clone judiciously)