Search code examples
javagenericscollectionstype-parameter

Aren't <U, T extends U> and <T, U super T> the same?


I have a confusion in following two method declarations:

    private <U, T extends U> T funWorks(T child, U parent) {
      // No compilation errors
    }

    private <T, U super T> T funNotWorks(T child, U parent) {
      // compilation errors    
    }

Shouldn't both of the above be valid? With the analogy of If U is parent of T , then T is child of U. Then why does 2nd one gives compilation error?

EDIT:: I think , T extends T and T super T both are valid. right ?


Solution

    • Type parameters (your example) can only use extends (JLS #4.4):
    TypeParameter:
        TypeVariable TypeBoundopt
    
    TypeBound:
        extends TypeVariable
        extends ClassOrInterfaceType AdditionalBoundListopt
    
    AdditionalBoundList:
        AdditionalBound AdditionalBoundList
        AdditionalBound
    
    AdditionalBound:
        & InterfaceType
    
    • Wildcards can use either extends or super (JLS #4.5.1):
    TypeArguments:
        < TypeArgumentList >
    
    TypeArgumentList: 
        TypeArgument
        TypeArgumentList , TypeArgument
    
    TypeArgument:
        ReferenceType
        Wildcard
    
    Wildcard:
        ? WildcardBoundsopt
    
    WildcardBounds:
        extends ReferenceType
        super ReferenceType