I believe that the type ?
in generics is a specific unknown type. Which means, declaring let's say a list of that type would prevent us from adding any type of object into it.
List<?> unknownList;
unknownList.add(new Object()); // This is an error.
The compiler gives an error as expected.
But when the unknown type is a second level generics, the compiler doesn't seem to care.
class First<T> {}
List<First<?>> firstUnknownList;
// All these three work fine for some reason.
firstUnknownList.add(new First<>());
firstUnknownList.add(new First<Integer>());
firstUnknownList.add(new First<String>());
I thought probably the compiler doesn't care about generic parameter in the second level at all, but it's not the case,
List<First<Integer>> firstIntegerList;
firstIntegerList.add(new First<String>()); // This gives a compiler error as expected.
So, why does the compiler allow us adding any kind of element when only an unknown element (and hence nothing) is acceptable in the second example?
Note: Compiler Java 1.8
new First<Integer>()
to theList<First<?>>
, what can you then do that is unsafe? Imagine that you've got a producer<T>
and a consumer<T>
method onFirst<T>
: you can't invoke the consumer; and you can get anObject
out of the producer. As such, there's nothing unsafe about it - unless I'm missing an obvious case. – Gnarlednull
. – GnarledList<?>
could have been assigned aList<Double>
and then adding an Object is wrong.List<Object>
would do. – Pauly