Generic methods and constructors are typically used when you need to introduce a type variable to constrain
the parameterized types of different parameters, or to constrain a parameter and the return type, as with
toArray. For example, consider a merge operation for SingleLinkQueue that moves the elements
from a source queue into a destination queue. To perform a merge, the elements of the source queue must be
the same as, or a subtype of, the elements of the destination queue. You can express this constraint with a
generic method by using a wildcard:
public static
SingleLinkQueue<? extends E> s)
{
// ... merge s elements into d ...
}
We could have introduced a second type variable, say S, to use instead of the wildcard to achieve the same
affect. So which is preferable? The general rule is to use wildcards when you can because code with wildcards
is generally more readable than code with multiple type parameters. When deciding if you need a type
variable, ask yourself if that type variable is used to relate two or more parameters, or to relate a parameter
type with the return type. If the answer is no, then a wildcard should suffice. In the above example, S would
appear in only one place and so can trivially be replaced by a wildcard.
A generic method need not be declared in a generic type, and if it is then the type variables are distinct. As
with inner generic types, if a generic method declares a type variable of the same name as that of a type
variable in the method's class or interface, the outer name is hidden. Finally, note that a static method such as
merge can be a generic method, though it cannot refer to any type variables of its own generic class.
11.3.1. Generic Invocations and Type Inference
If you invoke a generic method like toArray or merge, the compiler must ensure, as it does for all method
invocations, that you pass in arguments of the right type and assign any return value to a variable of the right
type. When you create an instance of a generic class, you use a parameterized type to bind a particular type
argument to the type variables of the class. Similarly, you can parameterize a method invocation to supply
type arguments for the method's type variables. For example, consider this generic method that simply returns
its argument:
return obj;
}
You can invoke passThrough as a String method:
String s1 = "Hello";
String s2 = this.
This parameterized method invocation tells the compiler that T should be treated as String and that the
arguments and return value of passThrough must be verified accordingly.
Fortunately, explicitly parameterizing a method invocation is rarely needed. In the absence of a type
argument, the compiler will infer what type to use from the static argument types and the way in which the
return type is used. For example, this invocation of passThrough is equivalent to the previous one but