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?
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)