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?
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With