Jason S
Jason S

Reputation: 189906

Java generic methods: super can't be used?

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?

Upvotes: 13

Views: 8069

Answers (3)

zw324
zw324

Reputation: 27210

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.

Upvotes: 8

Kerrek SB
Kerrek SB

Reputation: 477680

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

Upvotes: 2

Jason S
Jason S

Reputation: 189906

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

Upvotes: 1

Related Questions