提问者:小点点

克隆#克隆方法不必要的强制转换


class MyCls implements Cloneable {
  @Override
  protected MyCls clone() throws CloneNotSupportedException {
    return new MyCls(//...
  }
}

上面的代码没有任何问题。那么为什么CopyOnWriteArrayList#clone返回一个Object而不是CopyOnWriteArrayList?当从Object转换回所需类型时,编译器会哭泣。毕竟,这种设计决策的原因可能是什么?我看到这种模式在整个库中重复出现。

Ralph建议以下代码而不是上述代码是有效的:

@Override MyCls clone() throws CloneNotSupportedException { 
  MyCls clone = (MyCls)super.clone();
  clone.x = this.x; //or what ever to do return clone
  // ...
}

问题仍然是一样的。为什么CopyOnWriteArrayList#clone返回Object而不是本身?


共1个答案

匿名用户

您的问题基于协变返回类型,即使用更具体的返回类型覆盖方法的能力。

这个特性并不总是存在于Java,更准确地说,它是在Java引入的

但这并不意味着语言更新是先开发的,类是后开发的。这些类经历了一个在Java之前就开始的开发过程

所以早期版本必须声明与覆盖方法相同的返回类型,当它们与Java一起发布时

这不是一个独特的情况。

NIOBufferAPI引入了JDK

但是请注意,在类发布后更改方法以利用协变返回类型,当您在比预期运行的更新的JDK版本下编译代码时,可能会产生兼容性问题。解决方案,--release选项,也被引入到JDK