Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
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)'.
|