Почему дженерики полностью отключены, когда вы игнорируете тип параметра?

Как продолжение этого вопроса, сначала фон

Дан класс с этим объявлением:

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> {
    ...
}
Другие вопросы по тегам