Спецификация языка Java , раздел 8.4.2 пишет:
Ошибка времени компиляции объявлять два метода с
переопределить эквивалентные подписи
(определяется ниже) в классе.
Две сигнатуры метода m1 и m2 эквивалентны переопределению, если либо m1 является подписью m2, либо m2 является подписью m1.
Сигнатура метода m1 является подписями сигнатуры метода m2, если либо
м2 имеет ту же подпись, что и m1, или
подпись m1 такая же, как стирание подписи m2.
Очевидно, что методы не эквивалентны переопределению, поскольку ArrayList<String>
не ArrayList
(стирание ArrayList<Integer>
).
Итак, объявление методов законно. Кроме того, выражение вызова метода является допустимым, поскольку тривиально существует самый специфический метод , поскольку существует только один метод, соответствующий типам аргументов.
Редактировать : Ишай правильно указывает, что в этом случае есть еще одно ограничение. Спецификация языка Java, раздел 8.4.8.3 пишет:
Ошибка времени компиляции, если объявление типа T имеет метод-член
м1 и существует метод м2
объявленный в T или супертип T такой
что все следующие условия
держать:
- m1 и m2 имеют одинаковые имена.
- м2 доступен с T.
- Подпись m1 не является подписью (§8.4.2) подписи m2.
- m1 или некоторые переопределения метода m1 (прямо или косвенно) имеют такое же стирание, что и m2, или некоторые переопределения метода m2 (прямо или косвенно).
Приложение: об ersure и его отсутствии
Вопреки распространенному мнению, дженерики в сигнатурах методов не стираются. Обобщения стираются в байт-коде (набор инструкций виртуальной машины Java). Сигнатуры методов не являются частью набора команд; они записываются в файл класса, как указано в исходном коде. (Кроме того, эта информация также может быть запрошена во время выполнения с использованием отражения).
Подумайте об этом: если параметры типа полностью удалены из файлов классов, как может завершение кода в IDE по вашему выбору показать, что ArrayList.add(E)
принимает параметр типа E
, а не Object
(= удаление E
), если у вас не было прикрепленного исходного кода JDK? И как бы компилятор узнал, что выдает ошибку компиляции, когда статический тип аргумента метода не является подтипом E
?