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

JEP 390: Warnings for Value-Based Classes


    • Type: JEP
    • Status: Candidate
    • Priority: P3
    • Resolution: Unresolved
    • Fix Version/s: None
    • Component/s: None
    • Labels:
    • JEP Type:
    • Exposure:
    • Scope:
    • Discussion:
      valhalla dash dev at openjdk dot java dot net
    • Effort:
    • Duration:
    • JEP Number:



      Define a @ValueBased annotation, apply it to classes in the Java Platform API that may become inline classes in a future release, and provide warnings about improper attempts to synchronize on instances of such classes. Deprecate the constructors of the primitive wrapper classes for removal in order that these classes may be considered @ValueBased classes.


      The Valhalla Project is pursuing a significant enhancement to the Java programming model in the form of inline classes. Such classes declare their instances to be identity-free and capable of inline or flattened representations, where instances can be copied freely between memory locations and encoded using solely the values of the instances' fields.

      The design and implementation of inline classes is sufficiently mature that we can confidently anticipate migrating certain classes in the Java Platform to become inline classes in a future release. Specifically, a candidate inline class has the following properties:

      • Is final,

      • Declares only final instance fields,

      • Extends Object, or a hierarchy of abstract classes that declare no instance fields and have no instance initialization logic,

      • Declares only private constructors, or has deprecated its constructors for removal,

      • Does not promise a unique instance will be created with each factory-method invocation (or any other instance creation mechanism),

      • Does not rely upon or expose object identity through any of its methods,

      • Overrides toString, equals, and hashCode, and

      • Declares no synchronized methods, and discourages clients from performing synchronization.

      The Java Platform API uses the term value-based class to informally describe certain classes that satisfy similar constraints. If a class is described as value-based then it will probably be able to become an inline class.

      The primitive wrapper classes (java.lang.Integer, java.lang.Double, etc.) satisfy most of these constraints, but have public constructors that clients can invoke to guarantee a unique identity (e.g., for Integers used as locks). These public constructors have been deprecated since Java 9. If we now deprecate them for removal then the primitive wrapper classes can safely be considered value-based classes.

      When a value-based class becomes an inline class, its instances will be == based on their fields' values, and attempts to synchronize will throw an exception.

      These changes may be inconvenient for some, but the workarounds are straightforward: If you need an identity, use a different class—often one you define yourself, but Object or AtomicReference may also be suitable. The benefits of migrating to inline classes—better performance, reliable equality semantics, unifying primitives and classes—will be well worth the inconvenience.

      It will be helpful to warn developers of these risks several releases before the migration occurs. We therefore propose to standardize the value-based class terminology with an annotation, apply it to candidate inline classes in the JDK, and provide warnings to developers who synchronize on instances of such classes.


      The java.lang.ValueBased annotation interface will be introduced to indicate a class, interface, or method result for which no instances are expected to rely on object identity. The annotation declaration will describe the constraints outlined above, and communicate to developers that they should exercise caution when using == or identityHashCode, and should not perform synchronization.

      The @ValueBased annotation may be applied to the following declarations in the Java Platform API and the JDK:

      • The primitive wrapper classes in java.lang: Byte, Short, Integer, Long, Float, Double, Boolean, and Character;

      • The class java.lang.Runtime.Version;

      • The "optional" classes in java.util: Optional, OptionalInt, OptionalLong, and OptionalDouble;

      • Many classes in the java.time API: Instant, LocalDate, LocalTime, LocalDateTime, ZonedDateTime, ZoneId, OffsetTime, OffsetDateTime, ZoneOffset, Duration, Period, Year, YearMonth, and MonthDay, and, in java.time.chrono: MinguoDate, HijrahDate, JapaneseDate, and ThaiBuddhistDate;

      • The interface java.lang.ProcessHandle and its implementation classes;

      • The collection factories in java.util and their implementation classes: List.of, List.copyOf, Set.of, Set.copyOf, Map.of, Map.copyOf, Map.ofEntries, and Map.entry;

      • All subinterfaces and implementation classes—other than java.lang.String—of java.lang.constant.ConstantDesc, including ClassDesc, MethodTypeDesc, MethodHandleDesc, DirectMethodHandleDesc, DynamicCallSiteDesc, and DynamicConstantDesc, and the classes java.lang.Enum.EnumDesc and java.lang.invoke.VarHandle.VarHandleDesc; and

      • The value-based classes in the jdk.incubator.foreign module

      To make the primitive wrapper classes satisfy the constraints of @ValueBased classes, we will deprecate their constructors of for removal. (These constructors were originally deprecated in Java 9.)

      The following warnings will alert developers using these APIs that synchronization may fail in a future release:

      • javac will provide a warning category identifying synchronized statements that operate on @ValueBased classes and interfaces (factory method results receive limited treatment, since there's no type to track). We may want to make these warnings mandatory or specify them as a language feature, as with unchecked warnings.

      • HotSpot will provide an option to fail, log a warning, or emit a JDK Flight Recorder event when a monitorenter occurs for an instance of a @ValueBased class. For simplicity, HotSpot will not attempt to identify classes that implement a @ValueBased interface but are not themselves @ValueBased; it is the responsibility of the class author to apply these tags consistently.

      The monitorexit bytecode and the Object methods wait, notify, and notifyAll will thrown an IllegalMonitorStateException if invoked outside of a synchronized statement or method. There is thus no need for warnings about these operations.

      For example:

      @ValueBased final class Distance {
          final double meters;
          private Distance(double meters) { this.meters = meters; }
          public Distance ofMeters(double m) { return new Distance(m); }
      Distance d = Distance.ofMeters(20.0);
      synchronized (d) { ... } // javac warning & HotSpot warning
      Object o = d;
      synchronized (o) { ... } // HotSpot warning

      When a @ValueBased class becomes an inline class, the runtime warnings will be superseded by standard errors. At compile time, synchronization on an inline class type may also trigger a standard error. Compiler warnings will continue to be useful for interface types and method results.

      javac might also implement warnings for @ValueBased classes that violate the constraints of a @ValueBased class (non-final instance fields, toString method inherited from Object, etc.)


      We could abandon efforts to migrate these classes to be inline classes. However, there are significant benefits that developers will enjoy when we complete the migration, and the relative impact on developers who depend on problematic behavior is quite small.


      Migrating @ValueBased classes to be inline classes will require a reasonable amount of lead time with these warnings in place.

      Most significantly, a JEP to make the primitive wrapper classes inline will depend on completion of this JEP.


          Issue Links



              • Assignee:
                dlsmith Dan Smith
                dlsmith Dan Smith
                Dan Smith
                Reviewed By:
                Brian Goetz
                Endorsed By:
                Brian Goetz
              • Votes:
                0 Vote for this issue
                15 Start watching this issue


                • Created: