Highlights of new features between Java 11 and 17

Back to the blog

Contents

All changes

Before we start with the highlights: in case you want to learn more or have a complete view of all changes, just head to the Open JDK website.

Java 12

Not very interesting as a whole, but there are a few things to note at least.

String indentation and transforms

"text".indent(2); // adds two spaces
"text".indent(-2); // removes two spaces

String transformed = "text".transform(value ->
      new StringBuilder(value).reverse().toString()
);

Files.mismatch

long diff = Files.mismatch(fileA, fileB); 
// -1 means no diff, otherwise returns the first byte that differs

Collectors.teeing

double mean = Stream.of(1, 2, 3, 4, 5)
      .collect(Collectors.teeing(
             Collectors.summingDouble(i -> i), 
             Collectors.counting(), 
             (sum, count) -> sum / count)); // fork then join stream

Compact number formatting

NumberFormat likesShort = 
      NumberFormat.getCompactNumberInstance(
           new Locale("en", "US"), 
           NumberFormat.Style.SHORT);
likesShort.setMaximumFractionDigits(2);
likesShort.format(2592); // "2.59K"

Java 13

Nothing of interest really..

Just a bunch of previews, garbage collection and under the hood improvements.

Java 14

Compact switch cases is a nice addition, and JFR monitoring of live applications is niche, but useful.

Switch Expressions (JEP 361)

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

Java Flight Recorder Event Streaming (JEP 349)

Monitoring of code running live, e.g. in production, with low overhead

Java 15

Text blocks are nice, and sealed classes can be useful for library applications.

Text Blocks (JEP 378)

String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;

New garbage collection features (JEP 377 and JEP 379)

ZGC and Shenandoah are no longer experimental, although G1 is still the default.

Java 16

Records are finally here! Pattern matching is a nice addition, although in itself not a huge improvement. Better NullPointerExceptions are also long overdue as the default!

Pattern Matching for instanceof (JEP 394)

if (obj instanceof String s) {
    s.getBytes() // Use s instead of obj
}

Records (JEP 395)

record Point(int x, int y) {
  Point {
    if (x != y)  // implicit constructor parameters
      throw new IllegalArgumentException("..."));
    }
}

Point a = new Point(1,1);
a.x();
a.toString();
a.equals();

Helpful NullPointerExceptions (JEP 358)

int[] arr = null;
arr[0] = 1;

java.lang.NullPointerException: 
    Cannot store to int array because "arr" is null

Packaging Tool (JEP 392)

Create native install packages (msi, deb, rpm etc.) using the JDK.

Warnings for Value-Based Classes (JEP 390)

Integer a = new Integer(0); // Warning! 
// Should use Integer.valueOf(0) or auto-boxing with 0

Java 17 (LTS)

Sealed classes and stong encapsulation - mainly news for library maintainers, but expect to have to update dependencies!

Sealed Classes (JEP 360)

public abstract sealed class Person permits Employee, Manager {} 
// only allows Employee and Manager as sub-classes. 
// Also works for interfaces

public final class Employee extends Person {}
public non-sealed class Manager extends Person {}

Encapsulate JDK Internals (JEP 403)

Some of your dependencies might still use JDK internals using the relaxed encapsulation - this will not be possible starting from Java 17, so expect to update accordingly.