Java generic methods: super can't be used?

2019-01-15 00:23发布

问题:

So I have this method:

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

I'd like to return the collection instead of having a void method:

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

with the intent of doing something like this (where MyItemClass extends MyItemBaseClass):

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

but I get a syntax error on the super:

Syntax error on token "super", , expected

What gives? Can I fix this?

回答1:

Here's one link that explains why this is not allowed:

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

It basically just says that use super in type parameters "does not buy you anything", since if this is allowed, erasure will probably just erase it to Object, which does not make much sense.



回答2:

Here are two ideas. The first only returns a generic Collection, the second returns the actual result-type:

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;
}


回答3:

well, I didn't answer my question exactly, but this is an acceptable solution for my problem:

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