THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

parameterized type should always involve unbounded wildcards. For example, consider a non-generic version
of the passThrough method:


Object passThrough(Object o) {
return o;
}


and its subsequent use with an instance of List:


List l = new ArrayList();
Object o = passThrough(l);


List list1 = (List) o; // unchecked
List list2 = (List) o; // unchecked; raw type
List<?> list3 = (List) o; // OK: but raw type
List<?> list4 = (List<?>) o; // OK


The attempt to cast to List is effectively a cast to List<?> (or equivalently the raw type
List). At runtime we may have a list of some type but we can not be certain it is a List, so the
use of the cast gives an "unchecked" warning. The cast to the raw List type is itself okay, but the assignment
to list2 raises an "unchecked" warning because again there is no guarantee that the object is a
List. You can remove the "unchecked" warning by assigning to a variable of type List<?>, as
with list3 abovethe cast checks that the object is a list of some kind and that list3 can hold a reference to
a list of some kind. You should cast to List<?> instead of simply to List because it clearly expresses that
List is a generic type. The raw types exist for integration with legacy code that predates generics; when you
are writing code, it's better to consistently stick with the generic expression of the concept instead of the
legacy raw type.


The only places where use of a raw type is unavoidable are within a class literal expression and when
accessing static members. This reinforces the fact that what you are accessing is independent of any
parameterization of the generic type.


In some rare circumstances you may know for certain that a value has a particular parameterized type,[4] even
though the type system cannot verify that at runtime, and a cast to that parameterized type (with its ensuing
"unchecked" warning) is essential to allow your code to compile. As noted above, the fact that you need the
cast means that type information was lost, so your first response to this should be to avoid the loss of type
information in the first place. If you cannot do this you should clearly document why the "unchecked"
warning is occurring and why you are certain that the lack of a runtime type check is not a problem.


[4] Implementing a clone method is one such circumstancesee Section A.3.2 on page 747.

11.5.2. Overloading and Overriding


In Chapter 2 we defined overloaded methods to be methods having the same name but different signatures.
Later, in Chapter 3, we defined an overriding method to be a method in a subclass with the same name and the
same signature as an accessible method in the supertype. When a method signature involves type variables,
these definitions have to be adapted slightly.


First, the definition of "same signature" for two generic methods requires that they have the same number of
type variables with the same corresponding bounds. Further, after all the uses of the type variables in the
second method are renamed with the names of the type variables from the first method, the formal parameter

Free download pdf