| Safari Books Online |
4.1.3
section 4.1.3: |
From Java In a Nutshell, 5th Edition, section 4.1.3:
"Second, consider List methods such as add() that are declared to
accept an argument whose type is specified by the type parameter. This
is the more surprising case: when the type parameter is unknown, the
compiler does not let you invoke any methods that have a parameter of
the unknown type because it cannot check that you are passing an
appropriate value. A List<?> is effectively read-only since the
compiler does not allow us to invoke methods like add( ), set(), and
addAll( )."
This is incorrect and misleading.
First, the compiler *does* allow you to invoke the add() method in
this example -- it simply requires that a suitable value (a subtype of
the capture variable) be provided. The null reference is such a
value, and so it is always possible to write "l.add(null)" when l has
type List<?>.
Second, there are other ways to mutate a List<?> in addition to
directly invoking add(), set(), or addAll(). The clear() method, for
example, mutates a collection without making reference to the class's
type parameter. And methods like Collections.sort() allow a name to
be inferred for the unknown type, which then permits values of
inferred type T to be returned by get(), etc., and then passed to
add(), etc.
It's dangerous to suggest that a read-only interface to a collection
can be had by simply weakening its type argument. Instead,
programmers should be encouraged to use
Collections.unmodifiableList(), etc., and, for better compile-time
enforcement, consider weakening the type to Iterable<T> (this
interface still doesn't guarantee read-only access statically, though,
because the Iterator<T> interface has a remove() method).
—Dan
|
Anonymous |