-
Bug
-
Resolution: Fixed
-
P4
-
None
-
None
-
Verified
* 8.1.2
JLS7 said "Generic class declarations can be nested inside other declarations." but this sentence is pointless, as there is nothing in the definition of a generic class to suggest that it cannot be nested, and 9.1.2 doesn't bother with the corresponding claim for generic interfaces. Also, "other declarations" is poor wording, as it implies that a generic class declaration can be nested inside, say, a field declaration. Best to remove it.
* 8.1.3 Inner Classes
JLS7 said "Inner classes may not declare static initializers (§8.7) or member interfaces, or a compile-time error occurs." but the mention of member interfaces is unnecessary because the next clause covers them: "Inner classes may not declare static members, unless they are constant variables (§4.12.4), or a compile-time error occurs." (By 8.5.1, member interfaces are implicitly static.)
Moreover, the subsequent comment that "Member interfaces are implicitly static so they are never considered to be inner classes." is confusing, because inner classes are a kind of nested class and a nested class is always a class, not an interface. (Nested interfaces are introduced separately in ch.9.) So, while it's true that member interfaces are implicitly static, there is no point relating that to member interfaces not being inner classes. It would be more useful to stay wholly in the domain of nested classes, and say that: "A member class of an interface is implicitly static so is never considered to be an inner class."
* 8.9 Enum Types
1) JLS3 introduced two compile-time errors about references to enum constants that were carried over to JLS7 with minor corrections:
"It is a compile-time error to reference a static field of an enum type that is not a constant variable (§4.12.4) from constructors, instance initializer blocks, or instance variable initializer expressions of that type. It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant e to refer to e or to an enum constant of the same type that is declared to the right of e."
The first error is perfectly sensible. JLS3 introduced an example to explain it, and javac has always implemented it correctly. The second error is perplexing: a) it mentions constructors of an enum constant despite constructors not being allowed in the class body of an enum constant, b) it did not appear in the Proposed Final Draft of JSR 201, and c) it was never implemented by javac. It appears to be completely subsumed by the first error, so should be removed.
2) According to javac, a super(...) call is not allowed in a constructor of an enum type. It makes sense that arbitrary invocations of Enum's two-arg constructor are disallowed, but 8.9.2 Enum Body Declarations says nothing about superclass constructor invocation statements. Instead, 8.8.7 Constructor Body disallows a constructor of an enum from invoking the superclass constructor. That location is too obscure, so the rule should be moved to 8.9.2.
3) More generally, rules about enum bodies should be centralized in 8.9.2. This applies to rules that mention enums in 8.1.1, 8.1.1.1, 8.1.4, 8.8.3, and 8.8.9.
* 9.6.1 Annotation Type Elements
The clause "It is a compile-time error if the return type of a method declared in an annotation type is not one of the following: a primitive type, ..., or an array type whose element type is one of the preceding types." is wrong because it allows a nested array type int[][] (the element type int is after all one of the preceding types.) This is a rare case in the JLS of needing to say "component type" rather than "element type".
* 9.7 Annotations
The clause "An ElementValue is always FP-strict." is either incorrect or irrelevant depending on your view. On the one hand, an ElementValue is not formally an expression, and only expressions are FP-strict, so the clause is incorrect. On the other hand, an ElementValue is a wrapper for expressions, specifically constant expressions which are always FP-strict by definition, so speaking about the ElementValue being FP-strict is irrelevant. The clause should become informal narrative.
* 14.14.2 The enhanced-for Statement
1) Although the semantic meaning of an enhanced-for statement is specified in terms of a basic-for statement, the syntax of an enhanced-for statement is not specified in terms of the syntax of a basic-for statement. The syntactic production for an enhanced-for statement is independent of the syntactic production for a basic-for statement. Accordingly, the "no short if" rule for substatements (*) must be threaded into the syntactic production for an enhanced-for statement. An EnhancedForStatementNoShortIf production is needed which serves as one of the alternatives of ForStatementNoShortIf.
(*) In this code with a basic-for statement:
if (A)
for(...; ...; ...) if (B) X
else Y
the "else Y" clause belongs to the inner "if (B) X" statement, such that the overall statement is a plain if-then statement. The same should be true for an enhanced-for statement:
if (A)
for (... : ...) if (B) X
else Y
2) JLS7 chose to present the local variable declared in an enhanced-for statement as a FormalParameter. This simplifies the presentation (including in 6.3 where the scope of the variable is specified) but is confusing because an annotation whose type is applicable to a formal parameter declaration (ElementType.PARAMETER) cannot be written on the local variable. Instead, the annotation's type must be applicable to a local variable (ElementType.LOCAL_VARIABLE). It is best to revert to the JLS3 presentation for the variable, though using VariableDeclaratorId instead of Identifier because trailing [] are permitted: "for ( {VariableModifier} Type VariableDeclaratorId : ..."
JLS7 said "Generic class declarations can be nested inside other declarations." but this sentence is pointless, as there is nothing in the definition of a generic class to suggest that it cannot be nested, and 9.1.2 doesn't bother with the corresponding claim for generic interfaces. Also, "other declarations" is poor wording, as it implies that a generic class declaration can be nested inside, say, a field declaration. Best to remove it.
* 8.1.3 Inner Classes
JLS7 said "Inner classes may not declare static initializers (§8.7) or member interfaces, or a compile-time error occurs." but the mention of member interfaces is unnecessary because the next clause covers them: "Inner classes may not declare static members, unless they are constant variables (§4.12.4), or a compile-time error occurs." (By 8.5.1, member interfaces are implicitly static.)
Moreover, the subsequent comment that "Member interfaces are implicitly static so they are never considered to be inner classes." is confusing, because inner classes are a kind of nested class and a nested class is always a class, not an interface. (Nested interfaces are introduced separately in ch.9.) So, while it's true that member interfaces are implicitly static, there is no point relating that to member interfaces not being inner classes. It would be more useful to stay wholly in the domain of nested classes, and say that: "A member class of an interface is implicitly static so is never considered to be an inner class."
* 8.9 Enum Types
1) JLS3 introduced two compile-time errors about references to enum constants that were carried over to JLS7 with minor corrections:
"It is a compile-time error to reference a static field of an enum type that is not a constant variable (§4.12.4) from constructors, instance initializer blocks, or instance variable initializer expressions of that type. It is a compile-time error for the constructors, instance initializer blocks, or instance variable initializer expressions of an enum constant e to refer to e or to an enum constant of the same type that is declared to the right of e."
The first error is perfectly sensible. JLS3 introduced an example to explain it, and javac has always implemented it correctly. The second error is perplexing: a) it mentions constructors of an enum constant despite constructors not being allowed in the class body of an enum constant, b) it did not appear in the Proposed Final Draft of JSR 201, and c) it was never implemented by javac. It appears to be completely subsumed by the first error, so should be removed.
2) According to javac, a super(...) call is not allowed in a constructor of an enum type. It makes sense that arbitrary invocations of Enum's two-arg constructor are disallowed, but 8.9.2 Enum Body Declarations says nothing about superclass constructor invocation statements. Instead, 8.8.7 Constructor Body disallows a constructor of an enum from invoking the superclass constructor. That location is too obscure, so the rule should be moved to 8.9.2.
3) More generally, rules about enum bodies should be centralized in 8.9.2. This applies to rules that mention enums in 8.1.1, 8.1.1.1, 8.1.4, 8.8.3, and 8.8.9.
* 9.6.1 Annotation Type Elements
The clause "It is a compile-time error if the return type of a method declared in an annotation type is not one of the following: a primitive type, ..., or an array type whose element type is one of the preceding types." is wrong because it allows a nested array type int[][] (the element type int is after all one of the preceding types.) This is a rare case in the JLS of needing to say "component type" rather than "element type".
* 9.7 Annotations
The clause "An ElementValue is always FP-strict." is either incorrect or irrelevant depending on your view. On the one hand, an ElementValue is not formally an expression, and only expressions are FP-strict, so the clause is incorrect. On the other hand, an ElementValue is a wrapper for expressions, specifically constant expressions which are always FP-strict by definition, so speaking about the ElementValue being FP-strict is irrelevant. The clause should become informal narrative.
* 14.14.2 The enhanced-for Statement
1) Although the semantic meaning of an enhanced-for statement is specified in terms of a basic-for statement, the syntax of an enhanced-for statement is not specified in terms of the syntax of a basic-for statement. The syntactic production for an enhanced-for statement is independent of the syntactic production for a basic-for statement. Accordingly, the "no short if" rule for substatements (*) must be threaded into the syntactic production for an enhanced-for statement. An EnhancedForStatementNoShortIf production is needed which serves as one of the alternatives of ForStatementNoShortIf.
(*) In this code with a basic-for statement:
if (A)
for(...; ...; ...) if (B) X
else Y
the "else Y" clause belongs to the inner "if (B) X" statement, such that the overall statement is a plain if-then statement. The same should be true for an enhanced-for statement:
if (A)
for (... : ...) if (B) X
else Y
2) JLS7 chose to present the local variable declared in an enhanced-for statement as a FormalParameter. This simplifies the presentation (including in 6.3 where the scope of the variable is specified) but is confusing because an annotation whose type is applicable to a formal parameter declaration (ElementType.PARAMETER) cannot be written on the local variable. Instead, the annotation's type must be applicable to a local variable (ElementType.LOCAL_VARIABLE). It is best to revert to the JLS3 presentation for the variable, though using VariableDeclaratorId instead of Identifier because trailing [] are permitted: "for ( {VariableModifier} Type VariableDeclaratorId : ..."