Java Reference
In-Depth Information
List<String> l = new ArrayList<String>();
Object o = passThrough(l);
List<String> list1 = (List<String>) o; // unchecked
List<String> 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<String>
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<String>
, so the use of the
cast gives an "unchecked" warning. The cast to the raw
List
type is it-
self okay, but the assignment to
list2
raises an "unchecked" warning
because again there is no guarantee that the object is a
List<String>
.
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 parameteriz-
ation of the generic type.
In some rare circumstances you may know for certain that a value has
verify that at runtime, and a cast to that parameterized type (with its
ensuing "unchecked" warning) is essential to allow your code to com-
pile. 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