Summary
-------
Several minor bugs and enhancements in the Java Language Specification for the
"Records" feature [JEP 359](https://openjdk.java.net/jeps/359) have been identified, and addressed. The feature will remain a
preview feature for JDK 15.
Problem
-------
As a result of testing, discussion and feedback regarding the "Records" preview
feature, several issues in the JLS have been identified.
1. In Section 4.12.4 it was erroneously stated that the field corresponding to a
record component is another kind of variable that is implicitly declared
`final`.
2. In Section 8.10.1 it was erroneously stated that the `final` modifier can be
redundantly applied to record components.
3. Section 8.10.1: Given the following code, it is not clear from the
specification whether, when reflecting at runtime, the record component `s`
would be annotated with the annotation `@MyAnnotation` or not:
```
record R(@MyAnnotation String s) { ... }
```
4. In Section 8.10.1 it was erroneously stated that if the declared type of a
variable arity record component has a non-reifiable element type, then a
compile-time unchecked warning could be suppressed if the record type is
annotated with `@SafeVarargs`.
5. Section 8.10.4: The accessibility of the canonical constructor is required to
be `public`. This is unexpected and does not align with default constructors
in normal classes which have the same access modifier as the class.
6. Section 8.10.4: The following code compiles per the spec (as formal parameter
names are not part of a method/constructor signature):
```
public record R(int i) {
public R(int j) { // Different name for formal parameter
i = j;
}
}
```
7. Section 8.10.4: It is not clear if the following code compiles per the spec:
```
public record R(int i...) { // Variable-arity record component
public R(int[] i) { // Use array type for component
i=i;
}
}
```
8. Section 8.10.5: The design of compact constructor has been changed to exclude assignment to an instance field. The following definition of a compact constructor compiles
per the spec and is now an error:
```
record R(int i) {
R { this.i = 0; }
}
```
In addition, two design enhancements are proposed:
1. The previous specification treated local record declarations as a special
case. This caused some confusion (not least because the treatment of nesting
in the JLS is confusing). It is proposed that the specification is
refactored to allow more naturally for the local declaration of static types.
This allows for the new feature of supporting _local enums_ and _local
interfaces_.
2. Extend the use of the `@Override` annotation to declare that a method is an
accessor method for a record component.
Solution
--------
Addressing these issues:
1. Erroneous changes to Section 4.12.4 have been removed.
2. [8.10.1] The `final` modifier can not be applied to record components.
3. [8.10.1] The specification has been clarified to state that annotations on a
record component only remain on the record component if its
annotation type is applicable to record components.
4. [8.10.1] It was clarified that the `@SafeVarargs` annotation has to be
applied to the _canonical constructor_, not the record type, in order to
avoid an unchecked warning.
5. [8.10.4] The specification has been changed such that the accessibility of an
implicitly declared canonical constructor is the same as that of the record type. If
the canonical constructor is explicitly declared then its access modifier
must provide at least as much access at the record type.
6. [8.10.4] The specification now requires the names of record components and
formal parameters in canonical constructors to be identical.
7. [8.10.4] The specification requires that a formal parameter in a canonical
constructor must be a variable arity parameter if and only if the
corresponding record component is a variable arity record component.
8. [8.10.4] The specification now states that assignment to a field
corresponding to a record component of a record class in
the body of a compact constructor is a compile-time error.
Addressing the enhancements:
1. A number of changes have to made to support this enhancement:
- Two new specification documents have been produced: "Consistent Class and
Interface Terminology" clarifies the usage of terms related to classes and
interfaces, and more clearly distinguishes them from types; and "Local Static
Interfaces and Enum Classes" builds on this spec to support local
interface and enum class declarations.
- The Records specification now builds on top of the JLS as enhanced by the two
specification documents described above.
- [14.3] The Records specification now extends support of local interfaces and local
enum classes to additionally support local _records_.
2. [9.6.4.4] The specification has been enhanced to allow the use of the
`@Override` annotation to declare that a method is an accessor method for a
record component.
Specification
-------------
The updated specification is attached as `records-20200428.zip`. Inside of the `.zip` folder, apart from the specification file (records-jls.html) two other specification documents this specification builds on are included (class-terminology-jls.html) and (local-statics-jls.html). The previous specification, the one used for [JEP 359](https://openjdk.java.net/jeps/359) is also attached as records-jls-20200115.pdf