class MyCls implements Cloneable {
@Override
protected MyCls clone() throws CloneNotSupportedException {
return new MyCls(//...
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码没有任何问题。那么为什么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
// ...
}
Run Code Online (Sandbox Code Playgroud)
问题还是一样。为什么CopyOnWriteArrayList#clone返回Object而不是它自己?
您的问题基于协变返回类型,即使用更具体的返回类型覆盖方法的能力。
这个特性在 Java 中并不总是存在。更准确地说,它是在 Java 5 中引入的,该版本还引入了并发工具,包括CopyOnWriteArrayList.
但这并不是说先开发语言更新,然后再开发类。这些课程经历了在 Java 5 和更早版本之前开始的开发过程,草稿可以从http://gee.cs.oswego.edu/dl/concurrency-interest/下载
因此,早期版本必须声明与覆盖方法相同的返回类型,当它们与 Java 5 一起发布时,没有人及时考虑更改方法以使用协变返回类型。显然仍然没有人负责考虑它。它可能不够重要。
这不是一个独特的情况。
NIO BufferAPI 是在 JDK 1.4 中引入的,这是协变返回类型可能之前的一个版本,直到 Java 9,才添加了具有更具体返回类型的覆盖(例如ByteBuffer.position(int), limit(int), or clear(); 与仅继承版本的 Java 8版本相比,阻碍了 API 的流畅使用)。
但是请注意,在类发布后更改方法以使用协变返回类型,当您在比预期运行的 JDK 版本更新的情况下编译代码时,可能会产生兼容性问题。该解决方案的--release选项,也被介绍为晚9 JDK。
| 归档时间: |
|
| 查看次数: |
88 次 |
| 最近记录: |