JDK-8254944 : [JEP 390] Revise "value-based class" & apply to wrappers
  • Type: CSR
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P4
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 16
  • Submitted: 2020-10-16
  • Updated: 2020-12-07
  • Resolved: 2020-12-07
Related Reports
CSR :  
Relates :  
Description
Summary
-------

Revise the definition of "value-based class" to more accurately match expected future behavior of primitive classes, and update cross-references from API classes. Make the primitive wrapper classes (`Integer`, `Boolean`, `Double`, etc.) value-based classes.

Problem
-------

The primitive wrapper classes���`Boolean`, `Character`, `Byte`, `Short`, `Integer`, `Long`, `Float`, and `Double`���are slated to become *primitive classes* when the Valhalla project completes that feature. A *value-based class* in the current SE API claims a contract that is mostly compatible with eventually becoming a primitive class. To set programmers' expectations and smooth the transition, the primitive wrapper classes should thus adopt the *value-based class* terminology in their current specifications.

Certain details of the value-based class specification are not compatible with the wrapper classes or with the future requirements of primitive classes. The specification can be refined to reflect the needs of these uses cases.

Solution
--------

Update the value-based class specification as follows:

- Allow for use of `==` on instances, as long as the class ensures that behavior is consistent between instances that are equal (per `equals`), and that factories never promise to return unique instances if results are equal.

- Allow for non-private constructors if they are deprecated

- Allow factory methods to make promises about identity of results (like cacheing), as long as they do not promise a unique identity on each call

- Constrain classes to have no superclass fields or superclass initialization logic

- Clarify the distinction between requirements for classes and expectations for clients

Update the boilerplate used in references to this specification (links to `ValueBased.html`), allowing for use of `==`, but emphasizing the importance of treating `equal` instances as interchangeable, and that synchronization should be avoided.

Apply the boilerplate to the wrapper classes.

The `java.lang.ConstantDesc` classes don't fully satisfy the revised contract���e.g., they often inherit fields from superclasses. Remove the "value-based class" designation, and just say that clients shouldn't depend on identity.

We don't anticipate any negative compatibility impact. Third parties are not expected to declare their own value-based classes (this is an informal concept defined within the Java SE API to describe properties of its own classes). The expectations imposed on clients of value-based classes have been relaxed���they should continue to avoid synchronization, but some uses of `==` are okay. Of course, any further constraints imposed by the classes' own specifications remain in force.


Specification
-------------

Revised ValueBased.html:

```
 <body>
 <h1 id="ValueBased">{@index "Value-based Classes"}</h1>
 
Some classes, such as <code>java.lang.Integer</code> and
<code>java.time.LocalDate</code>, are <em>value-based</em>.
A value-based class has the following properties:
 <ul>
    <li>the class declares only final instance fields (though these may contain references
        to mutable objects);</li>
    <li>the class's implementations of <code>equals</code>, <code>hashCode</code>,
        and <code>toString</code> compute their results solely from the values
        of the class's instance fields (and the members of the objects they
        reference), not from the instance's identity;</li>
    <li>the class's methods treat instances as <em>freely substitutable</em>
        when equal, meaning that interchanging any two instances <code>x</code> and
        <code>y</code> that are equal according to <code>equals()</code> produces no
        visible change in the behavior of the class's methods;</li>
    <li>the class performs no synchronization using an instance's monitor;</li>
    <li>the class does not declare (or has deprecated any) accessible constructors;</li>
    <li>the class does not provide any instance creation mechanism that promises
        a unique identity on each method call&mdash;in particular, any factory
        method's contract must allow for the possibility that if two independently-produced
        instances are equal according to <code>equals()</code>, they may also be
        equal according to <code>==</code>;</li>
    <li>the class is final, and extends either <code>Object</code> or a hierarchy of
        abstract classes that declare no instance fields or instance initializers
        and whose constructors are empty.</li>
 </ul>
< p >When two instances of a value-based class are equal (according to 'equals'), a program
    should not attempt to distinguish between their identities, whether directly via reference
     equality or indirectly via an appeal to synchronization, identity hashing,
    serialization, or any other identity-sensitive mechanism.</p>
< p >Synchronization on instances of value-based classes is strongly discouraged,
    because the programmer cannot guarantee exclusive ownership of the
    associated monitor.</p>
< p >Identity-related behavior of value-based classes may change in a future release.
    For example, synchronization may fail.</p>
 </body>
 </html>
```
('p' tags have been tweaked to get them to render correctly in JBS.)

Updated cross-reference boilerplate, applied to existing value-based classes and the primitive wrapper classes:

     * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
     * class; programmers should treat instances that are
     * {@linkplain #equals(Object) equal} as interchangeable and should not
     * use instances for synchronization, or unpredictable behavior may
     * occur. For example, in a future release, synchronization may fail.

List of files with boilerplate spec updates (see attachment for diff):

    src/java.base/share/classes/java/lang/Boolean.java
    src/java.base/share/classes/java/lang/Byte.java
    src/java.base/share/classes/java/lang/Character.java
    src/java.base/share/classes/java/lang/Double.java
    src/java.base/share/classes/java/lang/Float.java
    src/java.base/share/classes/java/lang/Integer.java
    src/java.base/share/classes/java/lang/Long.java
    src/java.base/share/classes/java/lang/ProcessHandle.java
    src/java.base/share/classes/java/lang/Runtime.java
    src/java.base/share/classes/java/lang/Short.java
    src/java.base/share/classes/java/time/Duration.java
    src/java.base/share/classes/java/time/Instant.java
    src/java.base/share/classes/java/time/LocalDate.java
    src/java.base/share/classes/java/time/LocalDateTime.java
    src/java.base/share/classes/java/time/LocalTime.java
    src/java.base/share/classes/java/time/MonthDay.java
    src/java.base/share/classes/java/time/OffsetDateTime.java
    src/java.base/share/classes/java/time/OffsetTime.java
    src/java.base/share/classes/java/time/Period.java
    src/java.base/share/classes/java/time/Year.java
    src/java.base/share/classes/java/time/YearMonth.java
    src/java.base/share/classes/java/time/ZoneId.java
    src/java.base/share/classes/java/time/ZoneOffset.java
    src/java.base/share/classes/java/time/ZonedDateTime.java
    src/java.base/share/classes/java/time/chrono/HijrahDate.java
    src/java.base/share/classes/java/time/chrono/JapaneseDate.java
    src/java.base/share/classes/java/time/chrono/MinguoDate.java
    src/java.base/share/classes/java/time/chrono/ThaiBuddhistDate.java
    src/java.base/share/classes/java/util/KeyValueHolder.java
    src/java.base/share/classes/java/util/List.java
    src/java.base/share/classes/java/util/Map.java
    src/java.base/share/classes/java/util/Optional.java
    src/java.base/share/classes/java/util/OptionalDouble.java
    src/java.base/share/classes/java/util/OptionalInt.java
    src/java.base/share/classes/java/util/OptionalLong.java
    src/java.base/share/classes/java/util/Set.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/PaddingLayout.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java
    src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java
    test/lib/jdk/test/lib/hexdump/HexPrinter.java

Example spec change for `java.lang.constant.ConstantDesc`, `java.lang.constant.DynamicCallSiteDesc`,
and `java.lang.constant.DynamicConstantDesc`:

```
- * <p>Implementations of {@linkplain ConstantDesc} must be
- * <a href="../doc-files/ValueBased.html">value-based</a> classes.
+ * <p>Implementations of {@linkplain ConstantDesc} should be immutable
+ * and their behavior should not rely on object identity.
```

Comments
A reminder to be wary of == semantics of floating-point values for future iterations of this work. Moving to Approved.
07-12-2020

Okay. The warnings stand on their own, given the properties of the class���e.g., it's _already_ dangerous to synchronize on these things���but an extra "in the future" warning wouldn't hurt. I've added a sentence to the proposed ValueBased.html text and the proposed referencing boilerplate.
26-11-2020

Moving to Provisional, not Approved. For the boilerplate warning: > * <p>This is a <a href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a> > * class; programmers should treat instances that are > * {@linkplain #equals(Object) equal} as interchangeable and should not > * use instances for synchronization, or unpredictable behavior may > * occur. I'd prefer to see some indication of "clients of this type should follow these practices *now* to avoid some problems *in the future.*
25-11-2020

Diff of all changes is attached, 8254275.txt.
24-11-2020