在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是否利用协变返回类型