Search code examples
javagenericssuperclasssuper

Java generics: collection of super of super of some type


Consider the following self-contained sample:

import java.util.*;

class TestApplication
{

interface Type<C>
{
    Collection<Type<? super C>> getSuperTypes();
}

static class Test<C>
{
    private final Type<? super C> mySuperType = get( null );

    public Collection<Type<? super C>> getSuperTypes()
    {
        Collection<Type<? super C>> superTypes = new ArrayList<>();
        superTypes.add( mySuperType );

        //directly passing the super-types to addAll() works
        superTypes.addAll( mySuperType.getSuperTypes() );

        //but how can I declare the variable to temporarily hold the supers?
        Collection<Type<? super C>> superSuperTypes = mySuperType.getSuperTypes(); //ERROR
        superTypes.addAll( superSuperTypes );

        return superTypes;
    }
}

public static <T> T get( T value )
{
    return value;
}

}

So, I have this class which represents a type, and it has a super-type which in turn has super-types, and I want to have a function which returns a flat collection of all super-types of a type.

So, I declare a collection of super-types and I add to it the immediate super-type of the current type, and then I need to also add the super-types of the super-type. (Never mind that it is horrendously inefficient, in reality I do it in a much more efficient way, but that's irrelevant.)

So, the goal is to invoke superTypes.addAll() passing it the result of superType.getSuperTypes().

When the result of superType.getSuperTypes() gets directly passed to superTypes.addAll() without an intermediate variable, there is no problem.

But if I want to declare an intermediate variable superSuperTypes to hold the result of superType.getSuperTypes() before passing it to superTypes.addAll(), I cannot find a way to declare that variable so that it will compile. As it stands, it gives the following message:

Error:(100, 84) java: incompatible types: java.util.Collection<TestApplication.Type<? super capture#1 of ? super C>> cannot be converted to java.util.Collection<TestApplication.Type<? super C>>

So: how should superSuperTypes be declared in order to be able to assign to it the result of superType.getSuperTypes() and then pass it to superTypes.addAll() ?


Solution

  • Like so

    Collection<? extends Type<? super C>> superSuperTypes = mySuperType.getSuperTypes();