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
而不是本身?
您的问题基于协变返回类型,即使用更具体的返回类型覆盖方法的能力。
这个特性并不总是存在于Java,更准确地说,它是在Java引入的
但这并不意味着语言更新是先开发的,类是后开发的。这些类经历了一个在Java之前就开始的开发过程
所以早期版本必须声明与覆盖方法相同的返回类型,当它们与Java一起发布时
这不是一个独特的情况。
NIOBuffer
API引入了JDK
但是请注意,在类发布后更改方法以利用协变返回类型,当您在比预期运行的更新的JDK版本下编译代码时,可能会产生兼容性问题。解决方案,--release
选项,也被引入到JDK