Общие методы Java: super нельзя использовать?

Итак, у меня есть этот метод:

protected void collectSelectedItems(ListSelectionModel lsm, 
         Collection<? super MyItemClass> result) {
    for (int i : GUI.getSelectionIndices(lsm))
    {
        result.add(getItemByDisplayIndex(i));
    }
}

Я хотел бы вернуть коллекцию вместо метода void:

protected <T super MyItemClass> Collection<T> 
  collectSelectedItems(ListSelectionModel lsm, Collection<T> result) {
    for (int i : GUI.getSelectionIndices(lsm))
    {
        result.add(getItemByDisplayIndex(i));
    }
    return result;
}

с намерением сделать что-то вроде этого (где MyItemClass extends MyItemBaseClass):

List<MyItemBaseClass> list = 
   collectSelectedItems(lsm, new ArrayList<MyItemBaseClass>());

но я получаю синтаксическую ошибку на super:

Синтаксическая ошибка в токене "super", ожидается

Что дает? Могу ли я исправить это?


person Jason S    schedule 06.12.2011    source источник
comment
Что говорит ошибка?   -  person SLaks    schedule 06.12.2011
comment
Как вы хотите вызвать это?   -  person Kerrek SB    schedule 06.12.2011
comment
Object является надстройкой над MyItemClass, поэтому Collection может быть Collection<Object>. Не думаю, что здесь можно использовать super.   -  person Peter Lawrey    schedule 06.12.2011
comment
SLaks, Kerrek: только что отредактировал ответ для решения ваших проблем.   -  person Jason S    schedule 06.12.2011
comment
Питер, почему бы и нет? PECS: я передаю Cconsumer MyItemClass, поэтому мне нужно использовать super, а не extends   -  person Jason S    schedule 06.12.2011


Ответы (3)


Вот одна ссылка, которая объясняет, почему это не разрешено:

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeParameters.html#FAQ107

По сути, это просто говорит о том, что использование super в параметрах типа «ничего вам не покупает», поскольку, если это разрешено, стирание, вероятно, просто сотрет его до Object, что не имеет особого смысла.

person zw324    schedule 06.12.2011
comment
Это дает вам кое-что, если вы хотите объявить, что ваш метод принимает Comparator<? super Widget>, потому что Comparator<Object> вполне способен сортировать все подклассы Object. Но да, для коллекций это почти всегда неправильно. - person Trejkaz; 04.12.2014
comment
Это не то, что говорится на связанной странице - там явно говорится, что если бы super было разрешено в объявлениях method, это помогло бы создавать безопасные для типов универсальные методы. Прямо сейчас я наткнулся на пример с опцией orElse: он принимает только тот же тип, что и опцион, хотя часто имеет смысл сказать Optional<Subtype> optional = ...; Supertype result = optional.orElse(supertypeInstance); - person laszlok; 24.05.2018

Вот две идеи. Первый возвращает только общий тип Collection, второй возвращает фактический тип result:

public <T, S extends T> Collection<T> ver1(Collection<S> src, Collection<T> dst)
{
    dst.addAll(src);
    return dst;
}

public <U, T extends Collection<U>, S extends U> T ver2(Collection<S> src, T dst)
{
    dst.addAll(src);
    return dst;
}
person Kerrek SB    schedule 06.12.2011

ну, я точно не ответил на свой вопрос, но это приемлемое решение для моей проблемы:

protected <T extends Collection<? super MyItemClass>> 
  T collectSelectedItems(ListSelectionModel lsm, T result) {
    for (int i : GUI.getSelectionIndices(lsm))
    {
        result.add(getItemByDisplayIndex(i));
    }
    return result;
}
person Jason S    schedule 06.12.2011