Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8236894

(IGNORE) Changes to Records specification

    XMLWordPrintable

Details

    • CSR
    • Resolution: Withdrawn
    • P3
    • 14
    • specification
    • None
    • minimal
    • Hide
      Records are a preview feature in Java SE 14. It is possible that incompatible changes will be made to records in a later Java SE release, before they become final and permanent, but chances are low as records are ultimately Java classes so they shouldn't be introducing any new disruptive feature that could pose a compatibility risk. It is also possible that records will be removed in a later Java SE release, without ever having become final and permanent. Given that records have just been released there shouldn't be too much user code affected by these changes
      Show
      Records are a preview feature in Java SE 14. It is possible that incompatible changes will be made to records in a later Java SE release, before they become final and permanent, but chances are low as records are ultimately Java classes so they shouldn't be introducing any new disruptive feature that could pose a compatibility risk. It is also possible that records will be removed in a later Java SE release, without ever having become final and permanent. Given that records have just been released there shouldn't be too much user code affected by these changes

    Description

      Summary

      After the record's spec was released as several internal and external contributors have reported several bugs or clarification issues that should be fixed in the spec

      Problem

      The reported issues include:

      • names of formal parameters in canonical constructors must match the name of the corresponding record component
      • local records should not be allowed to capture any non-static state from any enclosing type
      • the 'final' modifier shouldn't be allowed to be redundantly applied to record components
      • clarify the interaction between records and @SafeVarargs annotation

      Solution

      Fix the mentioned issues in the spec

      Specification

      @@ -2230,14 +2230,14 @@
      
       #### **8.10.1 Record Components** {#jls-8.10.1}
      
       The _record components_ of a record type, if any, are specified by a list of
      -comma-separated parameter specifiers in the header of a record declaration.
      -Each record component consists of a type (optionally preceded by the `final`
      -modifier and/or one or more annotations) and an identifier (optionally
      -followed by brackets) that specifies the name of the record component. If a
      -record type has no record components, then the record header consists of an
      -empty pair of parentheses.
      +comma-separated parameter specifiers in the header of a record declaration. Each
      +record component consists of a type (optionally preceded by one or more
      +annotations) and an identifier (optionally followed by brackets) that specifies
      +the name of the record component. If a record type has no record components,
      +then the record header consists of an empty pair of parentheses.
      
      @@ -2250,14 +2250,15 @@
      
       *RecordComponent*:
      -: { *VariableModifier* } *UnannType* *VariableDeclaratorId*
      +: { *Annotation* } *UnannType* *VariableDeclaratorId*
       : *VariableArityRecordComponent*
      
       *VariableArityRecordComponent*:
      -: { *VariableModifier* } *UnannType* { *Annotation* } `...` *Identifier*
      +: { *Annotation* } *UnannType* { *Annotation* } `...` *Identifier*
      
       > It can be seen that the production for *RecordComponent* is identical in
      -> content to the production for *FormalParameter* ([8.4.1]).
      +> content to the production for *FormalParameter* ([8.4.1]), except a record
      +> component can not have a `final` modifier.
      @@ -2279,10 +2280,6 @@    
      -It is permitted for a record component to redundantly specify the `final`
      -modifier. It is a compile-time error if `final` appears more than once as a
      -modifier for a record component.
      -
       A record component may be a variable arity record component, indicated by an
       ellipsis following the type. At most one variable arity record component is
       permitted for a record type. It is a compile-time error if a variable arity
      @@ -2316,9 +2313,9 @@
      
       If the declared type of a variable arity record component has a non-reifiable
       element type ([4.7]), then a compile-time unchecked warning occurs for the
      -declaration of the variable arity record component, unless the record type is
      -annotated with `@SafeVarargs` ([9.6.4.7]) or the warning is suppressed by
      -`@SuppressWarnings` ([9.6.4.5]).
      +declaration of the variable arity record component, unless the canonical
      +constructor ([8.10.4]) is annotated with `@SafeVarargs` ([9.6.4.7]) or the
      +warning is suppressed by `@SuppressWarnings` ([9.6.4.5]).
      
       :::
      
      @@ -2480,8 +2477,8 @@
       If a canonical constructor is explicitly declared, then it must additionally
       satisfy the following conditions; otherwise a compile-time error occurs:
      
      -- The types of the formal parameters in the formal parameter list of the
      -canonical constructor must be identical to the declared type of the
      +- The names and types of the formal parameters in the formal parameter list of the
      +canonical constructor must be identical to the names and declared type of the
       corresponding record component.
      
       - A canonical constructor must not be generic ([8.8.4]).
      @@ -2567,12 +2564,16 @@     
      -In a record type _R_, the signature of a compact constructor declaration is
      -the derived constructor signature of _R_ ([8.10.4]).
      -
      -> Unlike constructors in records, and indeed in classes in general, no explicit
      -> formal parameter list is given for a compact constructor, but is derived from
      -> the record component list.
      +In a record type _R_, the formal parameter list for a compact constructor
      +declaration is implicitly declared and taken from the derived constructor
      +signature of _R_ ([8.10.4]).
      +
      +More precisely, in a record type _R_, the signature of a compact constructor
      +declaration is the derived constructor signature of _R_ ([8.10.4]).
      +
      +> This means that given a record type with a record component named *c*, in the
      +> body of compact constructor an occurrence of an unqualified name *c* denotes
      +> the implicit formal parameter *c*.
      
       It is a compile-time error to declare more than one compact constructor
       declaration for a record type.
      @@ -2587,7 +2588,8 @@
      
       - The compact constructor must be declared `public`.
      
      -- The body of a compact constructor must not contain a `return` statement ([14.17]).
      +- The body of a compact constructor must not contain a `return` statement
      +  ([14.17]).
      
       - The body of a compact constructor must not contain an explicit constructor
       invocation statement ([8.8.7.1]).
      @@ -2904,7 +2906,8 @@
           applicable to local variable declarations or type contexts.
      
       -  **a record component but *T* is not applicable to record component
      -declarations, field declarations, method declarations, or type contexts.**
      +   declarations, field declarations, method declarations, formal and exception
      +   parameter declarations, or type contexts.**
      
      @@ -3595,8 +3598,41 @@
      
       All local classes are inner classes ([8.1.3]).
      
      -**A *local record* is a record type declaration ([8.10]) that is not a member of
      -a class. A local record is implicitly `static`.**
      +:::inserted
      +
      +A *local record* is a record type declaration ([8.10]) that is not a member of
      +a class. A local record is implicitly `static`.
      +
      +It is a compile-time error if a local record contains a usage of a variable
      +declared in the enclosing block. 
      +
      +> Local records are constrained with regards to with variables they can access.
      +> The fact that a local record is implicitly `static` means that it is a
      +> compile-time error if a local record uses a non-`static` member of an
      +> enclosing class. It is permitted to use a `static` member of an enclosing
      +> class. Here is an example to illustrate the constraints. 
      +> 
      +> ```java
      +> class LocalRecordTest {
      +>     static int si;
      +>     int nsi;
      +> 
      +>     void m() {
      +>         int li;
      +> 
      +>         record R(int r) {
      +>             void print() {
      +>                 System.out.println(si);  // ok, static member of enclosing class
      +>                 System.out.println(nsi); // error, non-static member
      +>                 System.out.println(li);  // error, local variable
      +>             }
      +>         }
      +>     }
      +> }
      +> ```
      +
      +:::
      +
      
       Every local class declaration statement is immediately contained by a block
       ([14.2]).

      Attachments

        Issue Links

          Activity

            People

              gbierman Gavin Bierman
              vromero Vicente Arturo Romero Zaldivar
              Vicente Arturo Romero Zaldivar
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: