Search code examples
javagenericsnested-generics

Failing to compile correlated Java Generics parameters with wildcards


The following little Java example won't compile for unclear reasoning:

package genericsissue;

import java.util.ArrayList;
import java.util.List;

interface Attribute<V> {}

interface ListAttribute extends Attribute<List<?>> {}

public class Context {
    public <T, A extends Attribute<T>> void put(Class<A> attribute, T value) {
        // implementation does not matter for the issue
    }

    public static void main(String[] args) {
        Context ctx = new Context();
        List<?> list = new ArrayList<String>();
        ctx.put(ListAttribute.class, list);
    }
}

The line with ctx.put produces following error:

Context.java:18: <T,A>put(java.lang.Class<A>,T) in genericsissue.Context cannot be applied to (java.lang.Class<genericsissue.ListAttribute>,java.util.List<capture#35 of ?>)

If working without wildcards the attribute pattern works fine.

Is there any explanation why the compiler does not accept the value with wildcard typing?


Solution

  • Replace

    public <T, A extends Attribute<T>>
    

    With

    public <T, A extends Attribute<? super T>>