Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8251554 JEP 401: Value Classes and Objects (Preview)
  3. JDK-8317277

Java language implementation of value classes and objects

XMLWordPrintable

    • Icon: Sub-task Sub-task
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • None
    • tools
    • None

      This task summarizes the language changes introduced by JEP 401. All features are activated by the `--enable-preview` javac option.

      See full JLS changes at: https://cr.openjdk.org/~dlsmith/jep401/latest/

      ### 'value' classes and interfaces

      A class with the 'value' modifier, either concrete or abstract, is subject to the following rules:

      - All instance fields are implicitly 'final'
      - All fields must be initialized before the 'super' call (see also construction, below)
      - No instance methods may be 'synchronized'
      - Extends an abstract value class or 'Object'
      - If not 'abstract', is implicitly 'final'

      Abstract value classes may declare (final) instance fields.

      A record class may be declared a 'value record' and is subject to these rules.


      ### Value class construction

      As enabled by the Flexible Constructor Bodies JEP, any blank fields of a class may be assigned to before the 'super()' call.

      In value classes, there are two changes in the timing of implicit constructor code:

      - Instance field initializers are executed immediately upon entry to a non-'this()'-calling constructor.

      - An implicit 'super()' call occurs at the *end* of a constructor that lacks an explicit constructor call.

      Instance initializer blocks continue to run immediately after a 'super' call, wherever it occurs.

      These changes imply that, in value classes, instance field initializers and "simple" constructor bodies occur in an early construction context and are not allowed to invoke instance methods or otherwise improperly depend on 'this'.


      ### Readable fields in early construction

      Just as an instance field can be written during early construction, this JEP allows instance fields to be read (both in value classes and identity classes) if they are definitely assigned.

      Note that definite assignment analysis for instance fields will need to include field initializers (e.g., 'int x = (y = 3);').

      Instance fields of a class C may *not* be referenced from a lambda expression or a nested class in an early construction context of C.


      ### Record class constructors

      This JEP allows a normal canonical constructor for a record class to contain an explicit 'super()' call, expressing an explicit division between early and late construction.

      Tentatively, an identity record class is subject to the same construction rules as a value class:

      - A canonical constructor without an explicit 'super()' call runs during early construction, with the implicit 'super()' call placed at the end
      - A canonical constructor *with* an explicit 'super()' call requires all fields to be assigned before the call

      (If this is determined to be too much of a compatibility risk, we will either (1) place the implicit 'super()' call at the end, but tolerate record fields being assigned after an explicit 'super()' call, or (2) produce mandatory warnings for record classes that violate these restrictions, but leave the timing of the 'super()' call unchanged for now at run time.)


      ### 'synchronized' statements

      A compile-time error occurs if the type of the operand of a 'synchronized' statement is a concrete value class.


      ### Compilation

      See JDK-8317278 for class file format.

      The ACC_IDENTITY flag is unset on value classes, set on identity classes, and unset on interfaces.

      The ACC_STRICT flag is set for all instance fields declared by a value class or (if the tentative rules above are enforced) a record class.

      In each compiled class file, any concrete value class that appears in the descriptor of any declared or referenced field or method is named by the class file's `LoadableDescriptors` attribute.

      All value classes, record classes, and classes or interfaces that refer to APIs with concrete value class types (i.e., that have a `LoadableDescriptors` attribute) are generated with the preview version number.

      Bytecode generated for early construction must:

      - Cache the value of any field that is subsequently read in a "proxy" local variable, because fields of 'uninitializedThis' are not readable
      - Include StackMapTable entries, as necessary, that reflect the early initialization state of an instance when some of its fields have been set


      ### Class file reading

      When preview features are enabled, the following classes are considered to be value classes when loaded from class files:
      - java.lang.Number
      - java.lang.Record
      - All 8 primitive wrapper classes
      - All 4 java.util.Optional* classes
      - 12 java.time classes: Duration, Instant, LocalTime, Year, YearMonth, MonthDay, Period, LocalDate, LocalDateTime, OffsetTime, OffsetDateTime, ZonedDateTime
      - 5 java.time.chrono classes: ChronoLocalDateImpl, MinguoDate, HijrahDate, JapaneseDate, and ThaiBuddhistDate


      ### Compilation warnings

      The `serial` category of the javac `-Xlint` feature adds a warning for a concrete Serializable class that meets all of the following conditions, so cannot be serialized or deserialized: 1) either is a value class, or is an identity class that extends a Serializable abstract value class other than Number, 2) doesn't declare/inherit a writeReplace method of the appropriate form for serialization to use, 3) isn't a record, and 4) isn't a primitive wrapper class.

      A lint warning (category TBD) identifies code in instance field initializers and implicit-'super()' constructors of identity classes that would not be allowed in early construction due to a 'this' dependency. (This warning anticipates a future migration in which the early construction behavior of value classes is also applied to identity classes.) There is no warning for a field that is left unassigned before an explicit 'super(...)' call.


      ### Other language tools and APIs

      - 'javadoc' output indicates when a class is a value class.

      - 'javax.lang.model' is updated to support the 'value' modifier.

      - 'java.lang.invoke.LambdaMetafactory' may experiment with value classes as lambda classes.

            vromero Vicente Arturo Romero Zaldivar
            dlsmith Dan Smith
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: