Master Java 9‑16: Key New Features Every Developer Should Know

This article quickly reviews the major new features introduced in Java versions 9 through 16—including private interface methods, enhanced try‑with‑resources, var type inference, switch expression improvements, text blocks, records, refined NullPointerException messages, safe foreign‑memory access, jpackage tool, sealed classes, and new garbage collectors—so you can stay up‑to‑date and write modern Java code.

Programmer DD
Programmer DD
Programmer DD
Master Java 9‑16: Key New Features Every Developer Should Know

Java 9 (September 2017)

Private methods in interfaces

Java 8 added default methods; Java 9 allows private methods inside interfaces, which can be called from default methods, enabling code reuse without exposing the method.

public interface TestInterface {
    default void wrapMethod() {
        innerMethod();
    }
    private void innerMethod() {
        System.out.println("");
    }
}

Diamond operator for anonymous inner classes

Since Java 5 generics were introduced and Java 7 added the diamond operator (<>) for type inference. Java 9 extends support to anonymous inner classes.

List<Integer> numbers = new ArrayList<>();
List<Integer> numbers = new ArrayList<>() {
    ...
};

Enhanced try‑with‑resources

Java 7 introduced try‑with‑resources to automatically close resources. Java 9 allows using variables declared outside the try block as resources, simplifying code when multiple resources are needed.

try (BufferedReader bufferReader0 = new BufferedReader(...);
     BufferedReader bufferReader1 = new BufferedReader(...)) {
    System.out.println(br1.readLine() + br2.readLine());
}

Java 10 (March 2018)

Local variable type inference (var)

Java 10 adds the var keyword, enabling the compiler to infer the type of local variables, reducing boilerplate.

var message = "Hello, Java 10";

Java 11 (September 2018)

var in lambda parameters

Java 11 allows var in lambda parameters, with optional annotations.

List<String> languages = Arrays.asList("Java","Groovy");
String language = sampleList.stream()
    .map((@Nonnull var x) -> x.toUpperCase())
    .collect(Collectors.joining(", "));

Single‑file source‑code execution

Java 11 lets you run a single .java file directly without explicit compilation.

$ java HelloWorld.java
Hello Java 11!

Java Flight Recorder open‑sourced

Java Flight Recorder, a powerful diagnostic tool, is now part of OpenJDK.

Java 12 (March 2019)

Switch expression

Switch statements become expressions with arrow syntax and can return values.

typeOfDay = switch (dayOfWeek) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "Working Day";
    case SATURDAY, SUNDAY -> "Day Off";
};

Pattern matching for instanceof

Instanceof now supports a pattern that both tests and casts in one step.

if (obj instanceof String str) {
    int length = str.length();
}

Java 13 (September 2019)

Switch enhancements with yield

Switch expressions can contain blocks and use yield to return a value.

typeOfDay = switch (dayOfWeek) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> {
        // do sth...
        yield "Working Day";
    }
    case SATURDAY, SUNDAY -> "Day Off";
};

Text blocks

Multi‑line string literals are supported via text blocks, simplifying JSON or HTML strings.

String json = """
    {
        "id":"1697301681936888",
        "nickname":"空无",
        "homepage":"https://juejin.cn/user/1697301681936888"
    }
    """;

Java 14 (March 2020)

Records

Records provide a compact syntax for immutable data carriers, reducing boilerplate for POJOs.

public record UserDTO(String id, String nickname, String homepage) { }

Improved NullPointerException messages

NullPointerException now indicates which variable was null, making debugging easier.

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Boolean.booleanValue()" because the return value of "java.util.Map.get(Object)" is null
    at org.example.App.main(App.java:50)

Foreign‑memory access API

Java 14 introduces a safe API for off‑heap memory access, replacing unsafe operations.

// allocate 200 bytes of native memory
MemorySegment memorySegment = MemorySegment.allocateNative(200);
// write a long value
VarHandle varHandle = MemoryHandles.varHandle(long.class, ByteOrder.nativeOrder());
varHandle.set(memoryAddress, 10L);
memorySegment.close();

jpackage tool

jpackage bundles a Java application into a native installer or executable, eliminating the need for a separate JRE.

Java 15 (September 2020)

ZGC and Shenandoah GC

Low‑pause garbage collectors ZGC and Shenandoah become production‑ready.

Sealed classes

Sealed classes restrict which other classes or interfaces may extend or implement them.

public sealed interface Service permits Car, Truck {
    int getMaxServiceIntervalInMonths();
    default int getMaxDistanceBetweenServicesInKilometers() {
        return 100000;
    }
}

Java 16 (March 2021)

Java 16 continues to ship the preview features from earlier releases as standard, with no major new language changes.

Summary

These Java enhancements, many of which were experimental in earlier releases, quickly become stable, so learning them early helps you write modern, efficient Java code.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

programmingNew Featuresbackend-developmentjava-9-16
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.