为什么使用标准java类';s clone()返回对象而不是实际类型

为什么使用标准java类';s clone()返回对象而不是实际类型,java,Java,java允许指定函数返回的类型,例如下面的代码 public class Test { static class Dad { Dad me() { return this; } } static class Son extends Dad { Son me() { return this; } } } 这是有效的 让我们看看ArrayListcl

java允许指定函数返回的类型,例如下面的代码

public class Test {

    static class Dad {
        Dad me() {
            return this;
        }
    }

    static class Son extends Dad {
        Son me() {
            return this;
        }
    }
 }
这是有效的

让我们看看
ArrayList
class。它已经重写了
clone()
函数(至少我在OracleJDK1.7源代码中看到了它)

公共对象克隆(){
试一试{
@抑制警告(“未选中”)
ArrayList v=(ArrayList)super.clone();
v、 elementData=Arrays.copyOf(elementData,size);
v、 modCount=0;
返回v;
}捕获(CloneNotSupportedException e){
//这不应该发生,因为我们是可克隆的
抛出新的InternalError();
}
}

不返回
ArrayList
而只返回
Object
有什么意义?

一个原因是向后兼容。
Object.clone()
方法的签名早在Java 1.0中就指定了,当时不支持协变返回类型。如果他们按照您的建议更改了此基本方法,则可能会破坏数千个旧程序,
clone()
方法可能不会返回与
this
类型相同的对象

另见:


向后兼容性


在Java 5之前,重写时无法缩小返回类型,因此
ArrayList.clone()
被声明为返回
Object
。既然语言允许这样做,他们就不能使用它了,因为缩小
ArrayList.clone()
的返回类型会破坏现有的ArrayList子类,这些子类使用返回类型
Object
覆盖
ArrayList.clone()
,您可以编写一个复制方法。你不局限于克隆。如果现有的子类也发生了变化,它们可以
public Object clone() {
    try {
        @SuppressWarnings("unchecked")
            ArrayList<E> v = (ArrayList<E>) super.clone();
        v.elementData = Arrays.copyOf(elementData, size);
        v.modCount = 0;
        return v;
    } catch (CloneNotSupportedException e) {
        // this shouldn't happen, since we are Cloneable
        throw new InternalError();
    }
}