If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
One fixed-arity member method named m is more specific than another member method of the same name and arity if all of the following conditions hold:
- The declared types of the parameters of the first member method are T1, . . . , Tn.
- The declared types of the parameters of the other method are U1, . . . , Un.
- If the second method is generic then let R1 ... Rp p1, be its formal type parameters, let Bl be the declared bound of Rl, 1lp, let A1 ... Ap be the actual type arguments inferred (§15.12.2.7) for this invocation under the initial constraints Ti << Ui, 1in and let Si = Ui[R1 = A1, ..., Rp = Ap] 1in; otherwise let Si = Ui 1in.
- For all j from 1 to n, Tj <: Sj.
- If the second method is a generic method as described above then Al <: Bl[R1 = A1, ..., Rp = Ap], 1lp.
In addition, one variable arity member method named m is more specific than another variable arity member method of the same name if either:
- One member method has n parameters and the other has k parameters, where nk. The types of the parameters of the first member method are T1, . . . , Tn-1 , Tn[], the types of the parameters of the other method are U1, . . . , Uk-1, Uk[]. If the second method is generic then let R1 ... Rp p1, be its formal type parameters, let Bl be the declared bound of Rl, 1lp, let A1 ... Ap be the actual type arguments inferred (§15.12.2.7) for this invocation under the initial constraints Ti << Ui,1ik-1, Ti << Uk, kin and let Si = Ui[R1 = A1, ..., Rp = Ap] 1ik; otherwise let Si = Ui, 1ik. Then:
o for all j from 1 to k-1, Tj <: Sj, and,
o for all j from k to n, Tj <: Sk, and,
o If the second method is a generic method as described above then Al <: Bl[R1 = A1, ..., Rp = Ap], 1lp.
- One member method has k parameters and the other has n parameters, where nk. The types of the parameters of the first method are U1, . . . , Uk-1, Uk[], the types of the parameters of the other method are T1, . . ., Tn-1, Tn[]. If the second method is generic then let R1 ... Rp p1, be its formal type parameters, let Bl be the declared bound of Rl, 1lp, let A1 ... Ap be the actual type arguments inferred (§15.12.2.7) for this invocation under the initial constraints Ui << Ti, 1ik-1, Uk << Ti, kin and let Si = Ti[R1 = A1, ..., Rp = Ap] 1in; otherwise let Si = Ti, 1in. Then:
o for all j from 1 to k-1 , Uj <: Sj, and,
o for all j from k to n , Uk <: Sj, and,
o If the second method is a generic method as described above then Al <: Bl[R1 = A1, ..., Rp = Ap], 1lp.
The above conditions are the only circumstances under which one method may be more specific than another.
A method m1 is strictly more specific than another method m2 if and only if m1 is more specific than m2 and m2 is not more specific than m1.
A method is said to be maximally specific for a method invocation if it is accessible and applicable and there is no other method that is applicable and accessible that is strictly more specific.
If there is exactly one maximally specific method, then that method is in fact the most specific method; it is necessarily more specific than any other accessible method that is applicable. It is then subjected to some further compile-time checks as described in §15.12.3.
It is possible that no method is the most specific, because there are two or more methods that are maximally specific. In this case:
- If all the maximally specific methods have override-equivalent (§8.4.2) signatures, then:
o If exactly one of the maximally specific methods is not declared abstract, it is the most specific method.
o Otherwise, if all the maximally specific methods are declared abstract, and the signatures of all of the maximally specific methods have the same erasure (§4.6), then the most specific method is chosen arbitrarily among the subset of the maximally specific methods that have the most specific return type. However, the most specific method is considered to throw a checked exception if and only if that exception or its erasure is declared in the throws clauses of each of the maximally specific methods.
- Otherwise, we say that the method invocation is ambiguous, and a compile-time error occurs.
I will try to look into this one in the next days...