abstract method in indirect superclass

Stephan Herrmann stephan.herrmann at berlin.de
Sun Jul 7 09:46:18 PDT 2013

On 07/07/2013 05:36 PM, Remi Forax wrote:
> On 07/07/2013 05:03 PM, Stephan Herrmann wrote:
>> On 07/07/2013 04:44 PM, Remi Forax wrote:
>> > I don't see how this can compile despite the fact that both eclipse and javac
>> > are happy with this code :(
>> In fact this surfaced because a recent clean-up in ecj incidentally
>> changed this behavior so in 4.3 we no longer accept such code.
>> > foo(A) does not override foo(T2) if by example T2 is B so it should result in a name clash.
>> I don't think this part is at stake.
>> The signature of foo(A) is a subsignature of the signature of foo(T2)
>> because the former equals the erasure of the latter.
> it should because this is obviously a bug,
> this code throws a CCE
>     class A { }
>     class B extends A { }
>     class C extends A { }
>    abstract class X1<T1 extends A> {
>        void foo(T1 t) {
>          System.out.println("X1");
>        }
>    }
>    class X2<T2 extends A> extends X1<T2> {
>        @Override void foo(A t) {
>          System.out.println("X2");
>        }
>    }
>    class X3 extends X2<B> {
>      @Override void foo(B t) {
>        System.out.println("X3");
>      }
>    }
>    public class Test {
>      public static void main(String[] args) {
>        X2<B> x2 = new X3();
>        x2.foo(new C());
>      }
>    }

Thanks for the interesting example.
Here javac reports:

Test.java:17: error: name clash: foo(B) in X3 overrides a method whose erasure is the same as another method, yet neither overrides 
the other
     @Override void foo(B t) {
   first method:  foo(A) in X2
   second method: foo(T1) in X1
   where T1 is a type-variable:
     T1 extends A declared in class X1
1 error

For Java 7 this seems to be the right answer.
The fact that ecj is silent appears to be a bug.

I only wonder how this spells out in Java 8:

The relevant condition in JLS 7, reads:
"The signature of m1 or some method m1 overrides (directly or indirectly)
  has the same erasure as the signature of m2 or some method m2 overrides
  (directly or indirectly)."

Assuming that itself is not changed for JLS8,
we only have to make sure that "overrides" still includes the situation
of a method in an indirect superclass that was already overridden in
an intermediate class, viz., does X3.foo actually override X1.foo
although X1.foo was already overridden by X2.foo?
Looking at from spec 0.6.2, I'd say yes, the error reported
by javac is still valid.


More information about the lambda-spec-experts mailing list