Copy & Paste

an unoriginal site
A curated content list

A categorized list of all Java and JVM features since JDK 8 to 16

A categorized list of all Java and JVM features since JDK 8 to 16

8-Minute Read

Since the release of version 8, up to version 16, Java is shaped by 180 JDK Enhancement Proposals (JEPs), each of which brings some improvement to the platform. This page is a categorized and curated list of the most important improvements.

Contents of this page:

The full list of JEPs can be found on the OpenJDK website under the jdk and jdk9 projects.

All features are generally available and enabled by default, except if they are labelled with one of the following:

  • Preview πŸ” features are fully specified and implemented, but not yet considered to be final. They are considered to be almost complete, waiting for an additional round of real-world feedback. They have to be explicitly enabled.
  • Experimental πŸ’₯ features are less stable, and more likely to change. They also have to be explicitly enabled.
  • Incubator πŸ₯š modules are non-final tools and API’s, and are distributed in separate modules.

New Language Features

Since Java 8 lots of impactful improvements were made to the language. This section is a quick recap on what happened in the last years. For a more in-depth guide, see New language features since Java 8.

  • Sealed Classes can restrict which other classes may extend them (Preview πŸ”) JDK 16 JDK 15

    public abstract sealed class Shape
        permits Circle, Rectangle {...}
    public class Circle extends Shape {...} // OK
    public class Rectangle extends Shape {...} // OK
    public class Triangle extends Shape {...} // Compile error
    // No need for default case if all permitted types are covered
    double area = switch (shape) {
        case Circle c    -> Math.pow(c.radius(), 2) * Math.PI
        case Rectangle r -> r.a() * r.b()
  • Text Blocks JDK 15 (Preview πŸ” in JDK 14 JDK 13)

    String html = """
                        <p>Hello, world</p>
  • Switch Expressions JDK 14 (Preview πŸ” in JDK 12 JDK 13)

    int numLetters = switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> 6;
        case TUESDAY                -> 7;
        default      -> {
          String s = day.toString();
          int result = s.length();
          yield result;
  • Try-with-resources allows effectively final variables JDK 9 (Milling Project Coin)

New APIs

Let’s continue with the Java Standard Library, focusing on the new features that we can use in day-to-day coding.

If you are curious about all the API level differences between Java 8 later versions, check the AdoptOpenJDK/jdk-api-diff on GitHub or the The Java Version Almanac.


  • Stream.toList as convenience for the most typical collection method (instead of relying on .collect(Collectors.toList())) JDK 16

    List<String> result =
      Stream.of("one", "two", "three").stream()
        .filter(s -> s.length() == 3)
  • Stream.mapMulti to replace each element of this stream with zero or more elements, an alternative to flatMap JDK 16

    Stream.of(1, 2, 3, 4)
        .mapMulti((number, downstream) -> downstream.accept(number))
  • DateTimeFormatterBuilder.html#appendDayPeriodText to support other day periods than AM/PM JDK 16

  • Vector API to express computations that compile to optimal hardware instructions (Incubator πŸ₯š) JDK 16

  • Foreign linker API for statically-typed, pure-Java access to native code (Incubator πŸ₯š) JDK 16

  • Foreign memory access API to access memory outside of the Java heap (Incubator πŸ₯š) JDK 16

  • Collectors.teeing to create a Collector that is a composite of two downstream collectors JDK 12

  • Standard HTTP Client featuring HTTP/2, WebSocket support and non-blocking API JDK 11 (Incubator πŸ₯š in JDK 9)

    HttpClient httpClient = HttpClient.newBuilder().build();
    HttpRequest request =
    HttpResponse<String> response =
      httpClient.send(request, BodyHandlers.ofString());
  • Convenience Factory Methods for Collections to ease the pain of not having collection literals JDK 9

    Set<Integer> mySet = Set.of(1, 2, 3);
    List<Integer> myList = List.of(1, 2, 3);
    Map<String, Integer> myMap = Map.of("one", 1, "two", 2);
  • Reactive Streams publish-subscribe framework for asynchronous stream processing with non-blocking backpressure JDK 9

  • More options to transform (dropWhile, takeWhile) and generate (iterate, ofNullable) streams; readonly collectors (toUnmodifiableList); optionals can be transformed to streams JDK 9

  • Arrays.mismatch: find the first mismatching element between two arrays JDK 9

  • Process API provides more info and control (e.g. process ID, arguments, CPU time, parent/child processes), enhance ProcessBuilder to aid the creation of process pipelines JDK 9

  • VarHandle API to replace the field and array related operations of java.util.concurrent.atomic and sun.misc.Unsafe in order to and provide low-level access mechamisms, e.g. atomic write. JDK 9

  • Enhanced Deprecation policy. @Deprecated can be marked with forRemoval, which emits a new warning. JDK 9

  • OASIS Standard XML Catalog API to manage external resources in XMLs in a secure and performant manner JDK 9


`java.util.Locale` and related APIs support currency type, time zone and more [JDK 10](

Graphics and Desktop Applications

Desktop features for all platforms like login/logout/lock event listener and task bar interactions [JDK 9](
`MultiResolutionImage` that makes easy to retrieve a resolution-specific image for a DPI [JDK 9](

Performance Improvements


Elastic metaspace to return unused HotSpot class-metadata memory to the operating system more promptly [JDK 16](
Foreign-Memory Access API to safely and efficiently use off-heap memory (**Incubator** πŸ₯š) [JDK 15]( [JDK 14](
Application Class-Data Sharing to improve startup time and reduce footprint by sharing class metadata between Java processes. [JDK 10](
Class-Data Sharing archive of the default class list is enabled by default to improve out-of-the-box startup time [JDK 12](
Code caches of profiled and non-profiled compiled code is separated, resulting in improved performance and memory footprint [JDK 9](


Improved intrinsics for `java.lang.Math` `sin`, `cos` and `log` functions on AArch64 processors [JDK 11](
Improved GHASH and RSA performance by leveraging recently-introduced SPARC and Intel x64 CPU instructions [JDK 9](


Extra space on thread stack for critical sections, mitigating the risk of a deadlock in `java.util.concurrent` locks in case of a stack overflow [JDK 9](


Ahead-of-Time Compilation capability for Linux (**Experimental** πŸ’₯) [JDK 10]( (Graal as an experimental JIT Compiler) [JDK 9]( (JVM Compiler Interface) [JDK 9]( (Graal as an AoT Compiler)

G1 Garbage Collector (default)

Other Garbage Collectors

Z Garbage Collector, offering very low pause times on large heaps [JDK 16]( [JDK 15]( (**Experimental** πŸ’₯ in [JDK 14]( (Windows) [JDK 14]( (OS X) [JDK 11]( (Linux) )
Shenandoah Garbage Collector, offering similar benefits as ZGC but based on a different algorithm [JDK 15]( (**Experimental** πŸ’₯ in [JDK 12]( )
Epsilon Garbage Collector, which does not implement actual memory reclamation, striving for the lowest overhead possible [JDK 11](

Diagnostic and Tools

Flight Recorder Event Streaming: profiling data is available via an [API](, making it suitable for continuous monitoring [JDK 14](
Run-time manageable and method specific control of the C1 and C2 compilers that enables contained tests [JDK 9](
Fine-grained, easy-to-configure Logging System for all components of the JVM [JDK 9]( (Unified JVM Logging) [JDK 9]( (Unified GC Logging)

Security Improvements

Default set of root Certification Authority (CA) certificates are provided with the JDK, so TLS connections are working out of the box [JDK 10](


TLS Application-Layer Protocol Negotiation (ALPN) Extension which enables protocol negotiation without additional round trips; ALPN is a requirement for HTTP/2 connections [JDK 9](



Launch Single-File Source-Code Programs, including support for shebang (`#!`) line on Unix [JDK 11](
Compile for Older Platform Versions with `--release`, which configures `--source` and `--target` and links against the appropriate platform version [JDK 9](


Packaging Tool to create self-contained applications, also supporting native package formats: msi, exe, pkg, dmg, deb and rpm [JDK 16]( (**Incubator** πŸ₯š in [JDK 14]( β†’ Related: [Inside Java - Episode 12 β€œjpackage” with Kevin Rushforth](
`jlink` Java Linker that can build an optimized, slim run-time image for a modular Java application thag contains only the required parts of the JDK [JDK 9]( - [[2](], [[3](], [[4](], [[4](], [[5](]
Multi-Release JAR Files to allow multiple, Java-release-specific versions of class in a single archive [JDK 9](


  • The Javadoc tool now emits HTML5 markup instead of a frame-based layout and the documentation contains a search box to ease navigation JDK 9 - [2], [3]


Replace `Unsafe::defineAnonymousClass()` with `Lookup::defineHiddenClass()`, intended for frameworks to dynamically generate Hidden Classes that can’t be discovered, linked, and used directly by other classes. [JDK 15](
`java.lang.invoke.constant` package to allow easy description of loadable constants (operands for the `ldc` instruction), which is less error-prone than relying on ad-hoc String representation [JDK 12](
`CONSTANT_Dynamic` constant-pool entry which uses bootstrapping to perform the resolution, similarly to `INVOKEDYNAMIC` calls [JDK 11](
Introduction of the Nest access-control context that wraps classes in the same code entity - such as nested classes - and eliminates the need for compiler to insert bridge methods to the generated bytecode. [JDK 11](
Bytecode generated for static String-concatenation uses `invokedynamic` rather than directly creating `StringBuilder#append` chains. This will enable future optimizations of String concatenation without requiring bytecode changes.  [JDK 9](
`INVOKEDYNAMIC` can express high-level operations on object properties and or collections [JDK 9](

New supported platforms

New Version Scheme

Deprecation and removal

Deprecate the constructors of primitive wrapper classes, disallow synchronization on wrapper objects (`Byte`, `Short`, `Integer`, `Long`, `Float`, `Double`, `Boolean`, and `Character`) [JDK 16](
Deprecate [RMI Activation](, affecting the `java.rmi.activation` package and the `rmid` tool, does not affect Java RMI in general  [JDK 15](
Remove Launch-Time JRE Version Selection directives: `JRE-Version` manifest entry and `-version:` cli option  [JDK 9](
Remove the Endorsed Standards Override (`lib/endorsed`) and Extensions (`lib/ext`) mechanisms from the JRE [JDK 9](

If you are curious about all the API level differences between Java 8 and 14, check the Java Almanac project. Also check out jdeps, the Java class dependency analyzer to find out if your project is still using an old internal API.


JDK 8 was released in 2014. We had to wait for three and a half years for JDK 9. But since then things accelerated. Java has a new release structure that aims to deliver a new version in every six months.

While Java 8 is still supported, migrating to the latest version brings considerable amount of improvements to the table.

Original article:

Recent Posts



This place is just where I copy and paste articles I find interesting and can helpful for me in the future. No original content here!