Почему дженерики полностью отключены, когда вы игнорируете тип параметра?
Как продолжение этого вопроса, сначала фон
Дан класс с этим объявлением:
public class SomeClass<T>
И подкласс, который не использует универсальный параметр:
public class SomeSubClass extends SomeClass
Метод в SomeClass объявлен следующим образом:
protected Map<String, Object> getMap(Object param) {
}
Если подкласс вызывает метод следующим образом:
Map<String, Object> val = getMap(param);
По сути, компилятор жалуется, что getMap возвращает простую Map и существует непроверенное назначение обобщенной Map. Почему это так? Это документированные ожидания с Generics, и есть ли причина для этого?
2 ответа
Я не совсем знаю причину этого, но это поведение указано в спецификации языка Java JLS S4.8:
Суперклассы (соответственно, суперинтерфейсы) необработанного типа являются стиранием суперклассов (суперинтерфейсов) любого из его параметризованных вызовов.
Учитывая, что крайне нежелательно использовать типы Raw в новом коде, они хотели просто определить правила взаимодействия между типами Raw и параметризованными.
Это странно. Кажется, однако, что вы всегда можете избавиться от ошибки, не создавая проблем, расширяя SomeClass<Object>
вместо SomeClass
:
public class SomeSubClass extends SomeClass<Object> {
...
}