Parameterized Type Relationships
We know now that parameterized types share a common, raw
type. This is why our parameterized List<Date> is just a List at runtime. In fact, we can assign any
instantiation of List to the raw type
if we want:
Listlist=newArrayList<Date>();
We can even go the other way and assign a raw type to a specific instantiation of the generic type:
List<Date>dates=newArrayList();// unchecked warning
This statement generates an unchecked warning on the assignment, but
thereafter the compiler trusts that the list contained only Dates prior to the assignment. It is also
permissible, albeit pointless, to perform a cast in this statement. We’ll
talk about casting to generic types a bit later.
Whatever the runtime types, the compiler is running the show and does not let us assign things that are clearly incompatible:
List<Date>dates=newArrayList<String>();// Compile-time Error!
Of course, the ArrayList<String> does not implement the
methods of List<Date> conjured by
the compiler, so these types are incompatible.
But what about more interesting type relationships? The List interface, for example, is a subtype of the
more general Collection interface. Is a
particular instantiation of the generic List also assignable to some instantiation of
the generic Collection? Does it depend
on the type parameters and their relationships? Clearly, a List<Date> is not a Collection<String>. But is a List<Date> a Collection<Date>? Can a List<Date> be a Collection<Object> ...