Java Reference
In-Depth Information
The reason for this is simple—we don't know what the payload type of mysteryList
is! For example, if mysteryList was really a instance of ArrayList<String> , then
we wouldn't expect to be able to put an Object into it.
The only value that we know we can always insert into a container is null —as we
know that null is a possible value for any reference type. This isn't that useful, and
for this reason, the Java language spec also rules out instantiating a container object
with the unknown type as payload, for example:
// Won't compile
List <?> unknowns = new ArrayList <?>();
A very important use for the unknown type stems from the question, “Is
List<String> a subtype of List<Object> ?” That is, can we write this?
// Is this legal?
List < Object > objects = new ArrayList < String >();
At first glance, this seems entirely reasonable— String is a subclass of Object , so we
know that any String element in our collection is also a valid Object . However,
consider the following code:
// Is this legal?
List < Object > objects = new ArrayList < String >();
// If so, what do we do about this?
objects . add ( new Object ());
As the type of objects was declared to be List<Object> , then it should be legal to
add an Object instance to it. However, as the actual instance holds strings, then try‐
ing to add an Object would not be compatible, and so this would fail at runtime.
The resolution for this is to realize that although this is legal (because String inher‐
its from Object ):
Object o = new String ( "X" );
that does not mean that the corresponding statement for generic container types is
also true:
// Won't compile
List < Object > objects = new ArrayList < String >();
Another way of saying this is that List<String> is not a subtype of List<Object> .
If we want to have a subtyping relationship for containers, then we need to use the
unknown type:
// Perfectly legal
List <?> objects = new ArrayList < String >();
This means that List<String> is a subtype of List<?> —although when we use an
assignment like the preceding one, we have lost some type information. For exam‐
ple, the return type of get() is now effectively Object . You should also note that
List<?> is not a subtype of any List<T> , for any value of T .
Search WWH ::

Custom Search