Java 16

created onJuly 20, 2022

general availability on 2021-03-16

JEPs

new features

JEP state summary /remark
JEP 338: Vector API (Incubator) incubator provide an initial iteration of an incubator module, jdk.incubator.vector, to express vector computations that reliably compile at runtime to optimal vector hardware instructions on supported CPU architectures and thus achieve superior performance to equivalent scalar computations.
JEP 380: Unix-Domain Socket Channels standard add Unix-domain (AF_UNIX) socket support to the socket channel and server-socket channel APIs in the java.nio.channels package. Extend the inherited channel mechanism to support Unix-domain socket channels and server socket channels.
JEP 386: Alpine Linux Port standard port the JDK to Alpine Linux, and to other Linux distributions that use musl as their primary C library, on both the x64 and AArch64 architectures.
JEP 388: Windows/AArch64 Port standard port the JDK to Windows/AArch64. The focus of this JEP is not the porting effort itself, which is mostly complete, but rather the integration of the port into the JDK main-line repository.
JEP 389: Foreign Linker API incubator introduce an API that offers statically-typed, pure-Java access to native code. This API, together with the Foreign-Memory API (JEP 393), will considerably simplify the otherwise error-prone process of binding to a native library.
JEP 390: Warnings for Value-Based Classes standard designate the primitive wrapper classes as value-based and deprecate their constructors for removal, prompting new deprecation warnings. Provide warnings about improper attempts to synchronize on instances of any value-based classes in the Java Platform.
JEP 392: Packaging Tool standard Provide the jpackage tool, for packaging self-contained Java applications
JEP 393: Foreign-Memory Access API third incubator an API to allow Java programs to safely and efficiently access foreign memory outside of the Java heap. Applications include sharing memory across multiple processes, and serialization / deserialization of memory content by mapping files into memory (via, e.g., mmap).
JEP 394: Pattern Matching for instanceof standard instanceof now saves you from explicit, verbose casts. see comments on ‘JEP 305: Pattern Matching for instanceof (Preview)'
JEP 395: Records standard a new kind of restricted class for data containers without boiler code. see comments on ‘JEP 359: Records (Preview)'
JEP 396: Strongly Encapsulate JDK Internals by Default standard Code successfully compiled with earlier releases that directly accesses internal APIs of the JDK will no longer work by default. The strong encapsulation, which has been the default since JDK 9 can be relaxed with the JVM option –illegal-access. The sun.misc package will still be exported by the jdk.unsupported module, and will still be accessible via reflection. Hacking open private fields and protected or private methods of exported java.* APIs by reflection will result in an java.lang.reflect.InaccessibleObjectException.
JEP 397: Sealed Classes second preview allows the author of a class to specify which classes may extend the class. This allows for more fine grained control of inheritance hierarchies. see comments on ‘JEP 360: Sealed Classes (Preview)'

JDK internal

JEP summary /remark
JEP 347: Enable C++14 Language Features formally allow C++ source code changes within the JDK to take advantage of C++14 language features, and to give specific guidance about which of those features may be used in HotSpot code.
JEP 357: Migrate from Mercurial to Git migrate the OpenJDK Community’s source code repositories from Mercurial (hg) to Git.
JEP 376: ZGC move ZGC thread-stack processing from safepoints to a concurrent phase.
JEP 387: Elastic Metaspace return unused HotSpot class-metadata (i.e., metaspace) memory to the operating system more promptly, reduce metaspace footprint, and simplify the metaspace code in order to reduce maintenance costs.

deprecated

none

removed

none

some feature details

JEP 390: Warnings for Value-Based Classes

The design and implementation of primitive classes is sufficiently mature that certain classes of the Java Platform will become primitive classes in a future release.

The following changes are involved:

  • instances of these classes that are equal (per equals) may also be considered identical per ==,
  • attempts to create wrapper class instances with new Integer, new Double, etc., rather than implicit boxing or calls to the valueOf factory methods, will produce LinkageErrors.
  • attempts to synchronize on instances of these classes will produce exceptions.

To discourage misuse of value-based class instances, the following actions have been taken:

  • the primitive wrapper class constructors, originally deprecated in Java 9, have been deprecated for removal. Wherever the constructors are called in source, javac by default produces removal warnings. The jdeprscan tool may be used to identify usage of deprecated APIs in binaries.
  • javac implements a new warning category, synchronization, which identifies usages of the synchronized statement with an operand of a value-based class type, or of a type whose subtypes are all specified to be value-based. The warning category is turned on by default, and can be manually selected with -Xlint:synchronization.
  • HotSpot implements runtime detection of monitorenter occurring on a value-based class instance. The command-line option -XX:DiagnoseSyncOnValueBasedClasses=1 will treat the operation as a fatal error. The command-line option -XX:DiagnoseSyncOnValueBasedClasses=2 will turn on logging, both via the console and via JDK Flight Recorder events.

Identifying value-based classes

The @jdk.internal.ValueBased annotation is used to signal to javac and HotSpot that a class is value-based, or that an abstract class or interface requires value-based subclasses.

@ValueBased is applied to the following declarations in the Java Platform API and the JDK:

The primitive wrapper classes in java.lang;

  • the class java.lang.Runtime.Version;
  • Optional and friends 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.

Wherever the annotation is applied to an abstract class or interface, it is also applied to all subclasses in the JDK.

JEP 390: Packaging Tool

The jpackage tool packages a Java application into a platform-specific package that includes all of the necessary dependencies. The application may be provided as a collection of ordinary JAR files or as a collection of modules. By default, jpackage produces a package in the format most appropriate for the system on which it is run. The supported platform-specific package formats are:

  • Linux: deb and rpm
  • macOS: pkg and dmg
  • Windows: msi and exe

The following features are not included:

  • no GUI for the tool, only a command-line interface (CLI).
  • no support for cross compilation. I.e., in order to create Windows packages one must run the tool on Windows. The packaging tool will depend upon platform-specific tools.
  • no special support for legal files beyond what is already provided in JMOD files. There will be no aggregation of individual license files.
  • no native splash screen support.
  • no auto-update mechanism.

Being delivered as an incubator module named jdk.incubator.jpackage, the CLI options, application layout and other exported features are not guaranteed to remain stable and may be changed in a future release.

Examples of how to use jpackage are given in JEP 390 and here.

JEP 396: Strongly Encapsulate JDK Internals by Default

Code successfully compiled with earlier releases that directly accesses internal APIs of the JDK will no longer work by default.

The following packages of the JDK are Internal APIs:

  • sun.*
  • com.sun.*
  • jdk.*
  • org.*

Hacking open private fields and protected or private methods of exported java.* APIs by reflection will result in an java.lang.reflect.InaccessibleObjectException.

The sun.misc package will still be exported by the jdk.unsupported module, and will still be accessible via reflection.

The strong encapsulation, which has been the default since JDK 9 can be relaxed with the JVM option –illegal-access.

  • –illegal-access=permit allows access for packages that existed in JDK 8 for unnamed modules, including reflection. The first reflective-access operation to any private element (i.e. field, method) causes a warning to be issued, for subsequent reflective-access operations no warnings are issued after that point. This mode has been the default since JDK 9.
  • –illegal-access=warn is identical to permit except that a warning message is issued for every illegal reflective-access operation.
  • –illegal-access=debug is identical to warn except that both a warning message and a stack trace are issued for every illegal reflective-access operation.
  • –illegal-access=deny disables all illegal-access operations except for those enabled by other command-line options, e.g., –add-opens.

reference

OpenJDK JDK 16 Feature List and Schedule

JEP 390: Warnings for Value-Based Classes

JEP 390: Packaging Tool

JEP 396: Strongly Encapsulate JDK Internals by Default