《Effective Java》 读书笔记(十三) 谨慎重写clone方法

1.可以通过实现Cloneable接口重载对象的clone方法,若不实现Cloneable接口而重载clone方法,将会抛出CloneNotSupportedException异常。(这是比较反常的接口使用,因为Cloneable中没有任何方法,它所修改的父类上受保护方法的行为)
2.clone是唯一个创建对象但是却不需要调用构造方法的方法。
3.clone方法通用规范:创建并返回此对象的副本

  • 对于任何对象x,x.clone()!=x
  • x.clone().getClass()==x.getClass()

下面解析一下以上规则,x.clone()!=x,使用的是!=表示两个对象所引用的堆的对象的地址是不同的,因此不能用简单的Type x=y;进行复制,第二条:x.clone().getClass==x.getClass()用的是getClass而不是instanceof,说明是严格判断,对于派生类什么的是不行的。

想要实现以上规则,我们需要:

  • 对于每个clone方法中,给每个对象赋值的时候,需要调用对象的clone
  • 对于派生类,需要首先调用super.clone()

4.重写方法的返回类型可以是重写方法的返回类型的子类。

5.为了使一个类可以被克隆,可能需要从一些属性中移除final修饰符。

6.对于数组,链表,哈希表等容器,最好循环遍历赋值,而不是直接调用容器.clone

7.clone方法不能再构建过程中调用一个可以重写的方法。如果调用一个可重写的方法,子类很可能在克隆中的进行修复步骤之前执行该方法,这样可能会使得克隆和原始对象的损坏。

8.具有易用性的公共clone方法最好不要抛出CloneNotSupportedException

9.父类不应该实现Cloneable接口,而是应该交由给子类自己选择是否支持clone方法。

10.最好的clone方法:

  • 通过类似C++的拷贝构造函数:
    public Yum(Yum yum){...};

  • 通过静态工厂
    public static Yun newInstance(Yum yum){...};

总之,最好不要实现Cloneable接口,通常,复制功能最好由构造方法或者工厂提公,这个规则有个例外:数组最好使用clone方法复制。

猜你喜欢

转载自www.cnblogs.com/dengchengchao/p/9075621.html
今日推荐