-
Bug
-
Resolution: Not an Issue
-
P4
-
7
-
generic
-
generic
Example suggested by Sue:
public class GenericOverload {
interface Qoo<T> { void m(T arg); }
interface Roo<S extends Number> { void m(S arg); }
interface Ground extends Qoo<Integer>, Roo<Integer> {}
interface Param<T1, T2 extends Number> extends Qoo<T1>, Roo<T2> {}
void m(Ground g, Param<Integer, Integer> p, Integer i) {
g.m(i); // ambiguity error (ok in ecj)
p.m(i); // ambiguity error (also error in ecj)
}
}
The type Ground has members "Qoo<Integer>.m(Integer)" and "Roo<Integer>.m(Integer)". The same is true for type Param<Integer,Integer>.
JLS 15.12.1 is clear that Ground and Param<Integer,Integer> are the types to search (it calls it "class or interface" frequently in this section, but it's clear from reading the details that this means "class or interface type," including the type arguments).
15.12.2.1 says that both methods should be identified as potentially applicable. (In this and other sections, the only consistent interpretation of "method" is "the declared method, as instantiated by the type of which it is a member" -- the signature of the method is the signature after substitution. For example, in 15.12.2.2, we have "Let m be a potentially-applicable method ... let S1..Sn be the types of the formal parameters of m" -- and S1..Sn must be the types after substitution.)
From 15.12.2.5, "It is possible that ... there are two or more methods that are maximally specific. In this case: if all the maximally specific methods have override-equivalent signatures, then ... if all the maximally specific methods are declared abstract, and the signatures of all of the maximally specific methods have the same erasure, then the most specific method is chosen arbitrarily."
All of these conditions are met in both 'g.m(i)' and 'p.m(i)'.
public class GenericOverload {
interface Qoo<T> { void m(T arg); }
interface Roo<S extends Number> { void m(S arg); }
interface Ground extends Qoo<Integer>, Roo<Integer> {}
interface Param<T1, T2 extends Number> extends Qoo<T1>, Roo<T2> {}
void m(Ground g, Param<Integer, Integer> p, Integer i) {
g.m(i); // ambiguity error (ok in ecj)
p.m(i); // ambiguity error (also error in ecj)
}
}
The type Ground has members "Qoo<Integer>.m(Integer)" and "Roo<Integer>.m(Integer)". The same is true for type Param<Integer,Integer>.
JLS 15.12.1 is clear that Ground and Param<Integer,Integer> are the types to search (it calls it "class or interface" frequently in this section, but it's clear from reading the details that this means "class or interface type," including the type arguments).
15.12.2.1 says that both methods should be identified as potentially applicable. (In this and other sections, the only consistent interpretation of "method" is "the declared method, as instantiated by the type of which it is a member" -- the signature of the method is the signature after substitution. For example, in 15.12.2.2, we have "Let m be a potentially-applicable method ... let S1..Sn be the types of the formal parameters of m" -- and S1..Sn must be the types after substitution.)
From 15.12.2.5, "It is possible that ... there are two or more methods that are maximally specific. In this case: if all the maximally specific methods have override-equivalent signatures, then ... if all the maximally specific methods are declared abstract, and the signatures of all of the maximally specific methods have the same erasure, then the most specific method is chosen arbitrarily."
All of these conditions are met in both 'g.m(i)' and 'p.m(i)'.
- relates to
-
JDK-7034798 Ambiguity error for abstract method call is too eager
-
- Resolved
-
-
JDK-8013224 Most specific: spurious ambiguity error between abstract and default method
-
- Closed
-
-
JDK-7028828 15.12.2.5: Confusion in rules for maximally specific method disambiguation
-
- Closed
-
-
JDK-8148464 15.12.2.5: Unclear interpretation of a method's "erasure"
-
- Closed
-