This introduces one new overloaded form of m and defines two overriding implementations of m.
The simple rule to remember when thinking about overloading and overriding is to always consider the
erasure of the method signatures and to remember that you can't add genericity to an inherited method.
11.6. Finding the Right Method Revisited
In "Finding the Right Method" on page 224, we outlined the basic algorithm used by the compiler to
determine which form of a method should be invoked for a given method invocation expression. We can now
consider how generic types and generic methods (and constructors) affect that basic algorithm.
The changes to the algorithm can be summarized as follows:
If the method invocation includes explicit type arguments, then any potentially applicable generic
methods must have the same number of type parameters. Non-generic methods may also be
potentially applicable, in which case the actual type arguments are ignored.
1.
If there are no explicit type arguments in the invocation, and a generic method might be applicable,
then first the type arguments for the generic method are inferred based on the static types of the
argument expressions used in the method invocation. If no types that satisfy all the constraints on the
type parameters can be inferred, then the method is not applicable.
2.
At each phase, once the set of potentially applicable methods is determined, applicable methods are
searched for as previously described. For generic methods, either the explicit (if present) or the
inferred type arguments establish whether the argument type is compatible with the formal parameter
type.
3.
When the most specific method is searched for, type inference is again used when generic methods
are being considered. However, this time the type inference is not based on the actual argument
expression types; rather, the initial constraint is between the formal parameters of the generic method
and the formal parameters of the method against which it is being tested for being most specific. In
simple terms, the most specific test considers only the declared parameter types of the methods
concerned, not the type of the arguments used in the method invocation. This is clarified in an
example below.
4.
The search for the maximally specific method is not based on "same or different signature" but rather
on whether the signatures are override-equivalent (as previously described) or not.
5.
If the maximally specific method is a generic method, then the type of the method invocation
expression is the inferred return type of that generic method as determined by the type inference
applied as in point 2 above.
6.
For example, consider these two overloads of a method m:
void m(String key, Object val) {
// ...
}
<S, T extends Number> void m(S key, T val) {
// ...
}
Now consider this invocation of m:
m("hello", "world");