public static class Sup {
<T extends Runnable & Cloneable> void m(T arg) { System.out.println("Sup"); }
}
public static class Sub extends Sup {
<T extends Cloneable & Runnable> void m(T arg) { System.out.println("Sub"); }
}
Internally, the compiler treats this as an override. But the generated code includes Sup.m(Runnable)V and Sub.m(Cloneable)V, with no bridge between them.
ecj 3.8 has the same typing logic, but does generate a bridge.
Another possible (source-incompatible) approach is to decide that the two intersections are _not_ the same, so no overriding occurs. JLS is not extremely clear on this.
<T extends Runnable & Cloneable> void m(T arg) { System.out.println("Sup"); }
}
public static class Sub extends Sup {
<T extends Cloneable & Runnable> void m(T arg) { System.out.println("Sub"); }
}
Internally, the compiler treats this as an override. But the generated code includes Sup.m(Runnable)V and Sub.m(Cloneable)V, with no bridge between them.
ecj 3.8 has the same typing logic, but does generate a bridge.
Another possible (source-incompatible) approach is to decide that the two intersections are _not_ the same, so no overriding occurs. JLS is not extremely clear on this.
- duplicates
-
JDK-8166363 Method with reordered type parameter bounds compiles with @Override annotation but does not actually override superclass method.
- Closed
- relates to
-
JDK-8024484 8.4.2: Define when bounds are the same
- Open
-
JDK-8013846 javac fails to reject semantically equivalent generic method declarations
- Resolved