Тип стирания, переопределения и дженерики - PullRequest
36 голосов
/ 02 февраля 2009

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

@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, Standard Edition (сборка 1.5.0_16-b06-284). Что касается фрагмента кода, он уже выше, в значительной степени; вышеизложенное расширяет нижеследующее.

Ответы [ 2 ]

47 голосов
/ 02 февраля 2009

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

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

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

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

0 голосов
/ 02 февраля 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...