Finally, note that if you do wish to make a parameterized method invocation, you cannot parameterize an
invocation that uses just a simple method name:
String s1 = "Hello";
String s2 =
Instead you must qualify the method name appropriately, such as by using this or super for instance
methods, or the class name for static methods.
11.4. Wildcard Capture
Wildcards represent an unknown type, but whenever a variable that has a wildcard type is used, the compiler
must treat it as having some specific type so that it can check for correct usage. This specific (but still
unknown) type is referred to as the capture of the wildcard. The place you will most commonly come across
the capture of a wildcard is in the error messages the compiler produces when you use a parameterized type
the wrong way. For example, recall the incorrect attempt to add a String object to a queue accessed through
an unbounded wildcard reference:
SingleLinkQueue<?> strings =
new SingleLinkQueue
strings.add("Hello"); // INVALID: won't compile
The error message this produced from the compiler we used was:
add(capture of ?) in SingleLinkQueue<capture of ?> cannot be applied to (java.lang.String)
This is telling us that when the wildcard reference strings is used, the type of queue is
SingleLinkQueue<captureof?>, so the type of the parameter to add is also "captureof?".
Because String is not compatible with "captureof?" the call is not allowed. Even if the wildcard is
bounded, as in the earlier example with the queue of numbers ("?extendsNumber"), the type of the
parameter to add is "captureof?extendsNumber" which is still not compatible with Integer, even
though Integer is a subtype of Number.
If a wildcard is always represented by its capture, it would seem that once you have a wildcard type you can
only use it wherever a wildcard type is expected. Indeed this is a basic rule that ensures the integrity of the
type system.
However, as it stands this basic rule imposes a rather annoying restriction. A wildcard represents any type.
Similarly, the type variable of a generic method represents any type. But under the basic rule a wildcard type
can only be used where a wildcard type is expected. This precludes passing wildcard types to generic methods
that have a parameter defined by a type variable. Consider the synchronizedList utility method from the
Collections classpart of the java.util package discussed in more detail in Chapter 21. Its job is to
take an arbitrary list object and return a new list object that is backed by the original, but one for which all the
methods are synchronized to make access to the list thread-safe (see Chapter 14). The method is declared
as follows:
static