JDK-8252181 : [JEP 390] Define & apply annotation jdk.internal.ValueBased
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-08-21
  • Updated: 2020-12-14
  • Resolved: 2020-12-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 16
16 masterFixed
Related Reports
Blocks :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8253959 :  
JDK-8253961 :  
JDK-8253962 :  
JDK-8254797 :  
JDK-8255125 :  
Define a JDK-internal annotation, jdk.internal.ValueBased, which indicates that a class or interface is value-based, per:


Apply the annotation wherever existing documentation references ValueBased.html, including:

- The primitive wrapper classes in java.lang;

- 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 implementation classes of the collection factories in java.util: List.of, List.copyOf, Set.of, Set.copyOf, Map.of, Map.copyOf, Map.ofEntries, and Map.entry;

- [ Removed from JEP 390] - 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;

- [ Removed from JEP 390] - The value-based classes in the jdk.incubator.foreign module
Changeset: 48d8650a Author: Dan Smith <dlsmith@openjdk.org> Date: 2020-12-08 23:04:01 +0000 URL: https://git.openjdk.java.net/jdk/commit/48d8650a

Changing the behavior of existing classes by adding references to ValueBased.html is a spec change for each class. Though the warnings are applicable to JDK 16, the change in behavior cannot/should change for existing classes without the usual warning period. So if text is added to classes to be marked as @ValueBased, that text must make it clear that the class *will* change to value based in the future and is not value based currently. So when applied to existing value based classes, it is applicable. However, applying it to wrapper classes must be only a warning about a future change. For example, java.lang.Integer, is currently not a value-base class, it has identity. Perhaps the @ValueBased annotation needs a value to say it is a warning only, not an error.

Resolved: the annotation, jdk.internal.ValueBased, is purely a flag for javac and HotSpot. ValueBased.html will continue to act as part of the classes' specification. Third parties cannot get warnings for their own classes.

The concept of ValueBased and related warnings is not unique to the JDK, many frameworks and libraries could leverage the semantic importance of those classes. And it would help libraries and the users of those libraries to find and correct the incorrect assumptions. The case for keeping is private to the JDK should be articulated and the JEP JDK-8249100 updated to limit the scope.

Since `@ValueBased` is intended to annotate Java Platform API that may become inline classes in a future release and emits warnings, it can be a JDK internal API rather than a public Java SE API (like `@jdk.internal.reflect.CallerSensitive`) to enable javac and VM to detect the value-based classes. `@ValueBased` will not be needed once inline class support is in JDK and these types are migrated to inline classes. I think a JDK internal annotation will do the work.

Note that several classes other than the primitive wrappers are also considered to be "value-based". A quick grep through the sources for "ValueBased.html" results in the list below. There are some nuances here. Only the unmodifiable collections produced by List, Set, and Map factories are considered value-based. Also, it's Runtime.Version that's value-based, not Runtime itself. The annotation might or might not be applicable in these cases. 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/KeyValueHolder.java src/java.base/share/classes/java/util/List.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/java.base/share/classes/java/time/OffsetTime.java src/java.base/share/classes/java/time/ZonedDateTime.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/chrono/MinguoDate.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/ThaiBuddhistDate.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/YearMonth.java src/java.base/share/classes/java/time/Year.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/ZoneId.java src/java.base/share/classes/java/time/LocalDate.java src/java.base/share/classes/java/time/Period.java src/java.base/share/classes/java/time/ZoneOffset.java src/java.base/share/classes/java/lang/ProcessHandle.java src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java src/java.base/share/classes/java/lang/constant/ConstantDesc.java src/java.base/share/classes/java/lang/Runtime.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/ValueLayout.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MappedMemorySegment.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/GroupLayout.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryLayout.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemoryAddress.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/PaddingLayout.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/MemorySegment.java src/jdk.incubator.foreign/share/classes/jdk/incubator/foreign/SequenceLayout.java

java.lang seems like an appropriate package to declare the annotation, but if there's another, better host package, that's fine.