javagenerics

Java generic type resolution


I have started to work with Java recently and still got confused when dealing with generic types. The following is a simplified scenario where I am having some problems.

I have a class which holds a Map using a Class type as Key and an Collection of objects of that class:

public class GenericListInside {
    private Map<Class<?>, List<?>> mapping = new HashMap<>();

    public <T> void addListing(Class<T> clazz, List<T> object) {
        mapping.put(clazz, object);
    }
}

I can call addListing without problems:

GenericListInside gli = new GenericListInside();
List<Foo> list = new ArrayList<>(); 
//add something to list
gli.addListing(Foo.class, list); 

Now I decided to create a Class to provide a fluid interface. Something like:

with(Foo.class).use(list);

Then I came with:

public class FluidInserter<T> {
    Class<T> clazz;
    GenericListInside gli = new GenericListInside();

    public FluidInserter with (Class<T> clazz) {
        this.clazz = clazz;
        return this;
    }

    public <T> void use(List<T> list) {
        gli.addListing(clazz, list);
    }
}

But when I try to compile I get:

Error:(18, 12) java: method addListing in class util.GenericListInside cannot be applied to given types;
required: java.lang.Class,java.util.List
found: java.lang.Class,java.util.List
reason: inferred type does not conform to equality constraint(s)
inferred: T
equality constraints(s): T,T

This message is a little bit confusing... can anyone figure out what am I doing wrong?


Solution

  • The generic method of your fluid builder takes a generic method parameter, but that parameter is not the same as the type of your clazz field, despite the name overlap.

    Just remove <T> from your method declaration, while leaving List<T> as parameter:

    public void use(List<T> list) {
        gli.addListing(clazz, list);
    }
    

    Off-topic note: you don't want to return a raw typed FluidInserter in your with method. Change the return type to:

    public FluidInserter<T> with (Class<T> clazz)