Ваш вопрос основан на ковариантных типах возврата , то есть на возможности переопределить метод с более конкретным c типом возврата.
Эта функция не всегда существовала в Java. Если быть более точным, он был введен в Java 5, той же версии, которая также представила инструменты параллелизма, включая CopyOnWriteArrayList
.
Но это не значит, что сначала было разработано обновление языка, а классы - потом. Классы прошли процесс разработки, который начался до Java 5 и более ранних версий, и черновики можно было загрузить из http://gee.cs.oswego.edu/dl/concurrency-interest/
Таким образом, более ранние версии должны были объявлять тот же тип возвращаемого значения, что и замещаемый метод, и когда они были выпущены вместе с Java 5, никто вовремя не подумал об изменении метода для использования ковариантных возвращаемых типов. И, видимо, до сих пор никто из ответственных за это не учел. Это может быть недостаточно важно.
Это не уникальная ситуация.
API NIO Buffer
был представлен в JDK 1.4, на одну версию раньше, чем ковариантные возвращаемые типы были возможны, и это длилось до Java 9, прежде чем были добавлены переопределения с более конкретными c возвращаемыми типами (например, ByteBuffer.position(int)
, limit(int)
или clear()
; сравните с версией Java 8 , имеющей только унаследованные версии, которые препятствовали плавному использованию API).
Но помните, что изменение метода для использования ковариантных возвращаемых типов после того, как класс был опубликован, может создавать проблемы совместимости при компиляции кода под более новыми версиями JDK, чем предполагается. Решение, опция --release
, также было представлено в JDK 9.