Неожиданная синтаксическая ошибка в параметре типа метода

Почему это вызывает ошибку компиляции:

public <S super T> void addImplements(Class<S> cl)

тогда как это нормально:

public <S extends T> void addImplementedBy(Class<S> cl)

T — это параметр типа, указанный в классе. Сообщение об ошибке на первом Syntax error on token "super", , expected

обновить

Это, видимо, нормально:

public void addImplements(Class<? super T> cl)

По сути то же самое, но без именованного типа S.

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

Я не получаю «ничего вам не покупает» из связанного дубликата ответа. Во-первых, он покупает мне именованный тип S, который я могу использовать. Второй вариант (? super T) этого не предлагает.

Примечание одинаково для Java7 и Java8


person geert3    schedule 11.10.2015    source источник
comment
Возможный дубликат универсальных методов Java: super нельзя использовать?   -  person Faiz Halde    schedule 11.10.2015
comment
Каков будет ваш вариант использования для этого?   -  person Gaël J    schedule 11.10.2015
comment
обновил вопрос, чтобы показать альтернативный способ компиляции, хотя и без именованного типа S   -  person geert3    schedule 11.10.2015


Ответы (1)


Спецификация языка Java для Java SE 8 определяет параметр типа с:

TypeParameter:
{TypeParameterModifier} Identifier [TypeBound]

и Type Bound с :

TypeBound:
extends TypeVariable
extends ClassOrInterfaceType {AdditionalBound}

Таким образом, ключевое слово super явно не разрешено. Причина указана в часто задаваемых вопросах Анжелики Лангер по Java Generics:

Параметры типа могут иметь несколько верхних границ, но не могут иметь нижнюю границу. В основном это связано с тем, что параметры типов классов с нижней границей могут сбивать с толку и не особенно полезны.

person Ortomala Lokni    schedule 11.10.2015
comment
+1 за ссылку на синтаксис. Не уверен, хотя мне нравится запутывать здесь как действительный аргумент (если только они не имеют в виду, что это запутает синтаксический анализатор, но я в это не верю). Запутать программиста - не аргумент ИМХО. public <S extends List<Map<T, ArrayList<T>>>> getStuff() тоже может быть довольно запутанным. Мне просто нужно передать реализованный интерфейс моего класса T и пометить его S. - person geert3; 11.10.2015