Подтвердить что ты не робот

Тип стирания, переопределение и дженерики

Может кто-нибудь объяснить мне, почему

@Override
public void fooMethod(Class<?> c)

не отменяет

public void fooMethod(Class c)

и вместо этого дает мне следующие ошибки:

 - Name clash: The method fooMethod(Class<?>) 
of type SubClass has the same erasure as fooMethod(Class) of 
type SuperClass but  does not override it

 - The method fooMethod(Class<?>) of type 
SubClass must override a superclass method

?

Изменить: "java -version" говорит Java (TM) 2 Runtime Environment, стандартная версия (сборка 1.5.0_16-b06-284). Что касается фрагмента кода, он уже выше, в значительной степени; выше приведенное ниже.

4b9b3361

Ответ 1

Подпись fooMethod(Class<?>) совпадает с сигнатурой fooMethod(Class) после стирания, так как стирание Class<?> просто Class (JLS 4.6). Следовательно, fooMethod(Class) является подъявлением fooMethod(Class<?>), но не противоположным (JLS 8.4.2).

Для переопределения с помощью методов экземпляра нужен переопределяющий метод для подсигнала переопределенного метода (JLS 8.4.8.1). Это явно не так.

Теперь, когда мы установили, что ваш метод подкласса не переопределяет метод суперкласса в соответствии с JLS, давайте посмотрим на последствия выполнения во время стирания типа. Теперь у нас есть два метода, которые выглядят точно "одинаковыми" (одно и то же имя, одни и те же типы параметров), но не переопределяют друг друга. Если они не переопределяют, они должны быть доступны в подтипе как отдельные методы, но они имеют идентичные подписи времени выполнения: конфликт. Поэтому Java должен запретить его.

Переопределение общих типов параметров с использованием типов необработанных параметров разрешено, поскольку для этого существуют только типы типов: они являются удобным механизмом с конкретными правилами неправильного типа для взаимодействия с устаревшим кодом. Таким образом, система типов здесь решит, что метод подкласса переопределяет суперкласс, они идентичны после стирания типа, и у нас никогда не будет конфликта. Как следствие, эти библиотеки могут быть созданы независимо от существующего не общего кода.

Ответ 2

Потому что Class<?> более конкретный, чем просто Class.

Например, foo(Class<List>) не может переопределить foo(Class<Collection>). Я забываю термин, но типы с дженериками всегда будут отличаться от типов без.