This question already has an answer here:
I did not get this code to compile either way:
List<List> a = new ArrayList();
List<List<?>> b = new ArrayList();
a = b; // incompatible types
b = a; // incompatible types
It seems that java does not consider List
and List<?>
to be the same type when it comes to generics.
Why is that? And is there some nice way out?
Context
There is a library function with following signature: public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type)
. This works fine for simple types passed as argument but in case of generics the result is not parametrized with wildcard causing javac to complain about raw type. I would like to propagate the result to the rest of my application as Set<Class<? extends GenericTypeHere<?>>>
but simple cast does not work as I expect.
EDIT: Solution
Thanks for the answers, here is how I get it working in the end:
@SuppressWarnings({"rawtypes", "unchecked"})
private static Set<Class<? extends GenericTypeHere<?>>> factoryTypes() {
return (Set) new Reflections("...").getSubTypesOf(GenericTypeHere.class);
}
Okay, so this is due to a subtle semantic difference.
List
This is the raw type of List
, which equates to T
being of type Object
. So it's the same as saying:
List<Object>
Now, the Compiler knows for a fact, that whatever happens, this is a subclass of type Object
. And if you do..
List myList = new ArrayList();
myList.add(new Object());
It will work fine! This is because Object
is the same or it is some derivation of the type.
List<?>
This is literally a list of unknown (Java Docs). We don't even know that the subclass of the things in here are of type Object
. In fact, the ?
type is an unknown type all on its own. It has nothing to do with Object
! This is why when you try and do..
List<?> myList = new ArrayList<?>();
myList.add(new Object());
You get a compile time error!
List<? extends List> a = new ArrayList();
List<? extends List<?>> b = new ArrayList();
a = b;
works
Set<Class<? extends GenericTypeHere<?>>>
would imply
Set<Class<YourClass extends AnotherClass<YourClass>>>
as mentioned in the above wildcard answer
What stops you from using
Set<Class<YourClass extends AnotherClass>>
to propagate throughout your app?
来源:https://stackoverflow.com/questions/29055497/listlist-and-listlist-are-incompatible-types-in-java