为什么标准 java 类的 clone() 返回对象而不是实际类型



在java中可以指定函数返回的类型,例如下面的代码

public class Test {
    static class Dad {
        Dad me() {
            return this;
        }
    }
    static class Son extends Dad {
        Son me() {
            return this;
        }
    }
 }

有效。

让我们看看ArrayList类。它已经覆盖了clone()函数(至少我在Oracle jdk 1.7源代码中看到了它)

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();
    }
}

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

向后兼容性。

在Java5之前,重写时无法缩小返回类型,因此声明ArrayList.clone()返回Object。既然语言允许,他们就不能使用它,因为缩小ArrayList.clone()的返回类型会破坏ArrayList的现有子类,这些子类用返回类型Object覆盖ArrayList.clone()

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

另请参阅:

  • 在克隆中使用协变返回类型真的会破坏兼容性吗
  • 为什么不';Java 5+API是否利用协变返回类型

最新更新