-
Bug
-
Resolution: Unresolved
-
P4
-
8
-
generic
-
generic
The following should fail to compile, due to the signature erasure clash check in JLS 8.4.8.3, but succeeds. (The runtime behavior is then unexpected, due to a non-specified overriding via a bridge method.)
---
package a; public class A { /*package*/ Object m(Object arg) { return "a"; } }
package b;
public abstract class B<T> extends a.A {
public abstract Object m(T arg);
}
package a; public class C extends b.B<String> { public Object m(String arg) { return "b"; } }
---
Here, C has a member method C.m and there exists another method, A.m, declared in a supertype of C, such that:
- C.m and A.m have the same name
- A.m is accessible from C
- '(String)' is not a subsignature of '(Object)'
- The signature of a method that C.m overrides, B.m, has erasure '(Object)'; this is the same as the erasure of the signature of A.m
(One possible point of ambiguity is whether the "the signature of" B.m refers to its signature in B or its signature in C. If the latter, it has erasure '(Object)'. I don't think this is the intent, though, and some testing shows that this is not the interpretation javac generally uses for this error check.)
Another, similar example:
---
package a; public class A { /*package*/ Object m(Object arg) { return "a"; } }
package b;
public abstract class B<T> extends a.A {
public abstract Object m(T arg);
public Object m(String arg) { return "b"; }
}
package a; public class C extends b.B<String> {}
---
Here, C has a (inherited) member method 'B.m(String)' and there exists another method, A.m, declared in a supertype of C, such that:
- 'B.m(String)' and A.m have the same name
- A.m is accessible from C
- '(String)' is not a subsignature of '(Object)'
- The signature of a method that 'B.m(String)' overrides, 'B.m(T)', has erasure '(Object)'; this is the same as the erasure of the signature of A.m.
---
package a; public class A { /*package*/ Object m(Object arg) { return "a"; } }
package b;
public abstract class B<T> extends a.A {
public abstract Object m(T arg);
}
package a; public class C extends b.B<String> { public Object m(String arg) { return "b"; } }
---
Here, C has a member method C.m and there exists another method, A.m, declared in a supertype of C, such that:
- C.m and A.m have the same name
- A.m is accessible from C
- '(String)' is not a subsignature of '(Object)'
- The signature of a method that C.m overrides, B.m, has erasure '(Object)'; this is the same as the erasure of the signature of A.m
(One possible point of ambiguity is whether the "the signature of" B.m refers to its signature in B or its signature in C. If the latter, it has erasure '(Object)'. I don't think this is the intent, though, and some testing shows that this is not the interpretation javac generally uses for this error check.)
Another, similar example:
---
package a; public class A { /*package*/ Object m(Object arg) { return "a"; } }
package b;
public abstract class B<T> extends a.A {
public abstract Object m(T arg);
public Object m(String arg) { return "b"; }
}
package a; public class C extends b.B<String> {}
---
Here, C has a (inherited) member method 'B.m(String)' and there exists another method, A.m, declared in a supertype of C, such that:
- 'B.m(String)' and A.m have the same name
- A.m is accessible from C
- '(String)' is not a subsignature of '(Object)'
- The signature of a method that 'B.m(String)' overrides, 'B.m(T)', has erasure '(Object)'; this is the same as the erasure of the signature of A.m.
- relates to
-
JDK-8009685 Bridge methods change overriding behavior
-
- Open
-