-
Bug
-
Resolution: Fixed
-
P5
-
6u21, 6u65, 7u51, 8
-
b39
-
x86
-
linux
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8085452 | emb-9 | Maurizio Cimadamore | P5 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
Affects all versions I've tried, including
javac 1.6.0_21
javac 1.5.0_22
ADDITIONAL OS VERSION INFORMATION :
Debian GNU/Linux 5.0 (2.6.26-2-686-bigmem i686)
A DESCRIPTION OF THE PROBLEM :
The following classes compile fine with javac:
public abstract class Base<A> {
public abstract void go(A a);
public void go(String s) { System.out.println(s); }
}
public class Impl extends Base<String> { }
But the following do not, where the only difference is the order of the method declarations in Base:
public abstract class Base<A> {
public void go(String s) { System.out.println(s); }
public abstract void go(A a);
}
public class Impl extends Base<String> { }
resulting in this compile-time error:
Impl.java:1: Impl is not abstract and does not override abstract method go(java.lang.String) in Base
public class Impl extends Base<String> { }
^
1 error
According to the JLS3 introduction, "Declaration order is significant only for local variables, local classes, and the order of initializers of fields in a class or interface." This is such a fundamental feature of Java that clearly the compiler is wrong in at least one case.
The JLS seems inconsistent on this subject. According to 8.4.8.4, Base.go(String) should override Base.go(A) from the perspective of Impl, but that does not satisfy the strict definition of overriding in 8.4.8.1.
REPRODUCIBILITY :
This bug can be reproduced always.
Affects all versions I've tried, including
javac 1.6.0_21
javac 1.5.0_22
ADDITIONAL OS VERSION INFORMATION :
Debian GNU/Linux 5.0 (2.6.26-2-686-bigmem i686)
A DESCRIPTION OF THE PROBLEM :
The following classes compile fine with javac:
public abstract class Base<A> {
public abstract void go(A a);
public void go(String s) { System.out.println(s); }
}
public class Impl extends Base<String> { }
But the following do not, where the only difference is the order of the method declarations in Base:
public abstract class Base<A> {
public void go(String s) { System.out.println(s); }
public abstract void go(A a);
}
public class Impl extends Base<String> { }
resulting in this compile-time error:
Impl.java:1: Impl is not abstract and does not override abstract method go(java.lang.String) in Base
public class Impl extends Base<String> { }
^
1 error
According to the JLS3 introduction, "Declaration order is significant only for local variables, local classes, and the order of initializers of fields in a class or interface." This is such a fundamental feature of Java that clearly the compiler is wrong in at least one case.
The JLS seems inconsistent on this subject. According to 8.4.8.4, Base.go(String) should override Base.go(A) from the perspective of Impl, but that does not satisfy the strict definition of overriding in 8.4.8.1.
REPRODUCIBILITY :
This bug can be reproduced always.
- backported by
-
JDK-8085452 Order of declarations affects whether abstract method considered overridden
-
- Resolved
-
- relates to
-
JDK-7007615 java_util/generics/phase2/NameClashTest02 fails since jdk7/pit/b123.
-
- Closed
-