Community
Participate
Working Groups
Eclipse I20041201-1139 report the last call y.m(new Integer(2)) as ambiguous. JDK 1.5.0-b64 compiles without error and prints this: Y#m(Number): 1 Y#m(Number): 2 ----------------------------------------------------- class X<T> { public void m(Number num) {} public void m(T t) {} } class Y extends X<Number> { public void m(Number num) { System.out.println("Y#m(Number): " + num); } } class A { public static void main(String[] args) { Y y= new Y(); Number n= new Integer(1); y.m(n); y.m(new Integer(2)); // The method m(Number) is ambiguous for the type Y } }
I suspect that this is a javac bug. Once you define Y as class Y extends X<Number>, then it inherits 2 methods from X: public void m(Number num) {} public void m(<Number> t) {} So how can you ever send the 2nd one? How is m(Number) not ambiguous?
we should never accept this case: class X<T> { public void m(Number num) {} public void m(T t) {} } class Y extends X<Number> {} even javac complains that 2 methods are inherited with the same signature *** This bug has been marked as a duplicate of 80739 ***
I agree that the example in comment 2 should be rejected by the compiler. However, the original comment 0 was different. Method m(Number) is ambiguous in X<Number>, but not in Y, where it is redefined. Javac also flags references to X#m(Number) as ambiguous, such as when adding this to main: X<Number> xn= new X<Number>(); xn.m(n); //reference to m is ambiguous, both method // m(java.lang.Number) in xy.X<java.lang.Number> and method // m(T) in xy.X<java.lang.Number> match xn.m(new Integer(3)); //reference to m is ambiguous, both method // m(java.lang.Number) in xy.X<java.lang.Number> and method // m(T) in xy.X<java.lang.Number> match When the redeclaration of m(Number) is removed from Y, Y inherits (JLS3:8.4.8) two override-equivalent (JLS3:8.4.2) methods, which javac correctly flags as compile error (JLS3: 8.4.8.4) - but eclipse doesn't. In the original example, you indeed can never send a message to one of the two overridden override-equivalent methods (i.e. you can't call super.m(..) in Y#m(Number)), but this doesn't make up for a compile error by itself. Note that the methods from X are not inherited by Y, since they are overridden (JLS3:8.4.8).
"However, the original comment 0 was different." No its not. The declaration of Y is the same in both cases. It subclasses X in a way that causes 2 methods m(Object) to exist. That is an error that the verifier will catch as described by bug 80739. Whether Y reimplements m(Object) or not does not change that fact. The verifier will not skip over the fact that Y is incorrectly subclassing X just because it overrides the method. What is supposed to happen when Y decides to do a super.m() call?
For me, comment 0: class Y extends X<Number> { public void m(Number num) { /*...*/ } } looks different from comment 2: class Y extends X<Number> {} ;-) > Whether Y reimplements m(Object) or not does not change that fact. Oh yes, that's what I tried to "prove" with references to the not-yet-standard. Can you give me a pointer that shows why the reimplementation shouldn't matter? JLS3 8.4.8.4 'Inheriting Methods with Override-Equivalent Signatures' says: "It is possible for a class to inherit multiple methods with override-equivalent (ยง8.4.2) signatures. It is a compile time error if a class C inherits a concrete method whose signatures is a subsignature of another concrete method inherited by C." My point is that this section perfectly makes comment 2 erroneous, but does not affect the discussion of comment 0, since the methods are not inherited by Y. > What is supposed to happen when Y decides to do a super.m() call? That call is to be flagged as ambiguous at the invocation site, since there's no single overridden method X#m(Number). See JLS3: 15.12.2.5 'Choosing the Most Specific Method', last sentence. It's just too bad that Java has gotten so complicated that we need to have "language lawyers" as in the old C++ days :-(
ok, you're right. We handle this case differently.
So much for my ability to write proper English... Added GenericType test436
fixed.
Verified in 200412160010