Почему стандартные классы java clone() возвращают Object вместо фактического типа
В 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
?
Ответы
Ответ 1
Обратная совместимость.
До появления Java 5 возвращаемый тип не мог быть сужен при переопределении, поэтому ArrayList.clone()
было объявлено о возврате Object
. Теперь, когда язык позволяет это, они не могут его использовать, поскольку сужение возвращаемого типа ArrayList.clone()
приведет к поломке существующих подклассов ArrayList, которые переопределяют ArrayList.clone()
с типом возврата Object
.
Ответ 2
Одна из причин - обратная совместимость. Сигнатура метода Object.clone()
была указана еще в Java 1.0, когда не было поддержки ковариантных возвращаемых типов. Если они изменят этот фундаментальный метод, как вы предложили, он может сломать тысячи устаревших программ, в которых метод clone()
может не возвращать объект того же типа, что и this
.
Смотрите также: