JDK-7028828 : 15.12.2.5: Confusion in rules for maximally specific method disambiguation
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 5.0,7,8
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2011-03-17
  • Updated: 2018-08-03
  • Resolved: 2016-10-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
JLS 15.12.2.5 fails to specify the behavior of the following test case:

class Foo<T> {
  void m(Integer arg) {}
  void m(T arg) {}
}

void m1(Foo<Integer> f1, Integer i) {
  f1.m(i);
}

Class type Foo<Integer> has two methods with the same signature.  Of course, neither is more specific than the other.  Clearly, there should be an ambiguity error.  The behavior in such cases is outlined as follows:

1) If all the maximally specific methods have override-equivalent signatures, then:
  a) If exactly one of the maximally specific methods is not declared 'abstract', ...
  b) Otherwise, if all the maximally specific methods are declared 'abstract', and the signatures of all of the maximally specific methods have the same erasure, ...
2) Otherwise, we say the method invocation is ambiguous, and a compile-time error occurs.

There is no case 1c, for when neither 1a nor 1b are true.

As an aside, I think "the signatures of all of the maximally specific methods have the same erasure" is redundant, per 1.  That is

"all the maximally specific methods have override-equivalent signatures"
implies
"the signatures of all of the maximally specific methods have the same erasure"

Comments
Yes, the abstract part is valid, applied to the second bullet. So, if there's a family of identical abstract and default methods, the method is treated as if it were abstract. (Honestly, not sure at the moment why this matters for invocation, but that was how we designed it.) Example: abstract class C { abstract Number m(); } interface I { default Integer m() { return 23; } } abstract class D extends C implements I {} D d = ...; d.m(); // treated as an invocation of abstract 'm' with return type Integer
06-10-2016

The ... above includes a paragraph: "In this case, the most specific method is considered to be abstract. Also, the most specific method is considered to throw a checked exception ...". While the computation of thrown exceptions is still valid, the abstract part surely isn't.
03-10-2016

Updated text for 15.12.2.5: It is possible that no method is the most specific, because there are two or more methods that are maximally specific. In this case: [Note that the two-level bulleted list has been collapsed to a single level.] - If all the maximally specific methods have override-equivalent signatures (��8.4.2) ***and*** exactly one of the maximally specific methods is concrete (that is, ***neither*** abstract ***nor*** default), it is the most specific method. - Otherwise, if all the maximally specific methods are abstract or default, ***the signatures of these methods are override-equivalent, and the declarations of these methods have the same erased parameter types (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. ... - Otherwise, the method invocation is ambiguous, and a compile-time error occurs.
30-09-2016

The "have the same erasure" clause must be referring to the declaration-site erasure, which influences binary compatibility (13.1)���otherwise, choosing "arbitrarily" between different descriptors will lead to different types being mentioned in the class file.
30-09-2016

Clarification: "the signatures of all of the maximally specific methods have the same erasure" is unclear whether it means the declaration-site signatures or the instantiated signatures. So it's not safe to say that it is redundant, but it should be clarified (javac's interpretation is declaration-site erasure). While addressing this bug, we should make sure we understand the intent of "the signatures of all of the maximally specific methods have the same erasure" -- it's not clear to me whether it is having the intended effect; in any case, it needs to be clarified.
12-09-2013

Also note that override-equivalent methods do not necessarily have the same erasure, per JDK-8024484.
12-09-2013