Java 22: The Latest Features and Improvements

Java 22 introduces several innovative features and enhancements designed to improve developer productivity, performance, and ease of use. Below is a comprehensive overview of these new features, explained both technically and in layman's terms, along with code examples where applicable.

JDK 22 delivers 12 enhancements that are significant enough to warrant their own JDK Enhancement Proposals (JEPs), including seven preview features and one incubator feature. They cover improvements to the Java Language, its APIs, its performance, and the tools included in the JDK.

Language Improvements

  • Language Previews
    • Statements before super (…) [Preview] - JEP 447
    • String Templates (Second Preview) - JEP 459
    • Implicitly Declared Classes and Instance Main Methods (Second Preview) - JEP 463
  • Libraries
    • Foreign Function & Memory API - JEP 454
    • Library Previews and Incubator
      • Class-File API (Preview) - JEP 457
      • Stream Gatherers (Preview) - JEP 461
      • Structured Concurrency (2nd Preview) - JEP 462
      • Scoped Values (2nd Preview) - JEP 464
      • Vector API (7th Incubator) - JEP 460
  • Performance
    • Regional Pinning for G1 - JEP 423
  • Tooling

    • Launch Multi-File Source-Code Programs - JEP 458

Language Preview


1. Statements before super(...) [Preview] - JEP 447

  • Technical Explanation: This feature allows statements to be executed before a call to super(...) in a constructor. It is particularly useful for performing initializations or setting up preconditions that are required by the superclass constructor.
  • Layman Explanation: Imagine you need to do some setup or checks before calling the parent class's constructor. This feature lets you do that directly within the constructor.
  • Refer: Source Oracle Docs

Code Example

class Parent {
    Parent(int value) {
        System.out.println("Parent constructor: " + value);
    }
}

class Child extends Parent {
    Child(int value) {
        if (value <= 0) {
            throw new IllegalArgumentException("Value must be positive");
        }
        super(value);
        System.out.println("Child constructor");
    }
}

public class Main {
    public static void main(String[] args) {
        new Child(5);
    }
}

2. String Templates (Second Preview) - JEP 459

  • Technical Explanation: String Templates provide a more readable and maintainable way to embed expressions within string literals. This feature aims to improve code clarity and reduce the risk of injection vulnerabilities.
  • Layman Explanation: This feature lets you mix text and variables in strings more easily and safely, making your code easier to read and write.
  • Refer: Source Oracle Docs

Code Example

String name = "Alice";
int age = 30;
String message = STR."Hello, my name is \{name} and I am \{age} years old.";
System.out.println(message);

3. Implicitly Declared Classes and Instance Main Methods (Second Preview) - JEP 463

  • Technical Explanation: This feature allows for a simpler way to define classes and instance main methods, reducing boilerplate code in simple applications and scripts.
  • Layman Explanation: It makes writing small programs easier by allowing you to skip some of the usual setup code.
  • Refer: Source Oracle Docs

Code Example

public class Main {
    void main() {
        System.out.println("Hello, world!");
    }
}

Libraries


1. Foreign Function & Memory API - JEP 454

  • Technical Explanation: This API facilitates interaction with native code and memory, providing a safer and more efficient alternative to the Java Native Interface (JNI). It includes features for managing native memory and calling foreign functions.
  • Layman Explanation: It allows Java programs to safely and efficiently use functions and memory from non-Java (native) libraries, which can be important for performance or accessing system-level resources.
  • Refer: Source Oracle Docs

Code Example

import jdk.incubator.foreign.*;
import static jdk.incubator.foreign.CLinker.*;
public class Main {
    public static void main(String[] args) {
        try (ResourceScope scope = ResourceScope.newConfinedScope()) {
            MemorySegment memory = MemorySegment.allocateNative(100, scope);
            memory.set(JAVA_INT, 0, 42);
            int value = memory.get(JAVA_INT, 0);
            System.out.println("Value: " + value);
        }
    }
}

Library Previews and Incubator


1. Class-File API (Preview) - JEP 457

  • Technical Explanation: The Class-File API allows for the reading and writing of Java class files. This feature supports advanced manipulation of Java bytecode.
  • Layman Explanation: This tool helps developers who need to read or modify the internals of compiled Java programs (class files).
  • Refer: Source Oracle Docs

Code Example

import jdk.internal.classfile.*;
public class Main {
    public static void main(String[] args) throws Exception {
        ClassFile cf = ClassFile.read("MyClass.class");
        System.out.println("Class Name: " + cf.name());
    }
}

2. Stream Gatherers (Preview) - JEP 461

  • Technical Explanation: Stream Gatherers provide a way to collect multiple streams of data into a single stream, improving the handling of asynchronous data sources.
  • Layman Explanation: This feature makes it easier to combine data coming from different places into one stream for processing.
  • Refer: Source Oracle Docs

Code Example

Stream<Integer> stream1 = Stream.of(1, 2, 3);
Stream<Integer> stream2 = Stream.of(4, 5, 6);
Stream<Integer> gatheredStream = Stream.of(stream1, stream2).flatMap(s -> s);
gatheredStream.forEach(System.out::println);

3. Structured Concurrency (2nd Preview) - JEP 462

  • Technical Explanation: Structured Concurrency simplifies handling multiple concurrent tasks by ensuring that they are managed in a structured, predictable manner. It aims to improve the reliability and readability of concurrent code.
  • Layman Explanation: It helps manage multiple tasks running at the same time in a more organized way, making the code easier to understand and less error-prone.
  • Refer: Source Oracle Docs

Code Example

import java.util.concurrent.*;
public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        try (var executor = new StructuredTaskScope.ShutdownOnFailure()) {
            Future<Integer> future1 = executor.fork(() -> 1);
            Future<Integer> future2 = executor.fork(() -> 2);
            executor.join();
            System.out.println("Results: " + future1.resultNow() + ", " + future2.resultNow());
        }
    }
}

4. Scoped Values (2nd Preview) - JEP 464

  • Technical Explanation: Scoped Values provide a way to share immutable data within a specific scope, offering an alternative to thread-local variables with better performance and simpler semantics.
  • Layman Explanation: It allows you to share data within a limited area of your program in a safer and more efficient way than using thread-local storage.
  • Refer: Source Oracle Docs

Code Example

import jdk.incubator.concurrent.ScopedValue;
public class Main {
    static final ScopedValue<String> SCOPED_VALUE = ScopedValue.newInstance();
    public static void main(String[] args) {
        try (var scope = ScopedValue.enter(SCOPED_VALUE, "Hello")) {
            System.out.println(SCOPED_VALUE.get());
        }
    }
}

5. Vector API (7th Incubator) - JEP 460

  • Technical Explanation: The Vector API provides a mechanism for expressing vector computations that are translated at runtime to efficient vector instructions on supported hardware, improving performance for data-parallel operations.
  • Layman Explanation: It helps programs that process large amounts of data run faster by using specialized hardware instructions.
  • Refer: Source Oracle Docs

Code Example

import jdk.incubator.vector.*;
public class Main {
    public static void main(String[] args) {
        VectorSpecies<Integer> SPECIES = IntVector.SPECIES_256;
        int[] a = {1, 2, 3, 4, 5, 6, 7, 8};
        int[] b = {8, 7, 6, 5, 4, 3, 2, 1};
        int[] c = new int[8];

        IntVector va = IntVector.fromArray(SPECIES, a, 0);
        IntVector vb = IntVector.fromArray(SPECIES, b, 0);
        IntVector vc = va.add(vb);
        vc.intoArray(c, 0);

        for (int value : c) {
            System.out.println(value);
        }
    }
}

Performance


1. Regional Pinning for G1 - JEP 423

  • Technical Explanation: This enhancement to the G1 garbage collector allows it to pin regions of memory, improving performance by reducing the overhead of garbage collection pauses.
  • Layman Explanation: It makes the part of the Java system that cleans up unused memory run faster and with fewer delays.
  • Refer: Source Oracle Docs

This feature is primarily a performance improvement within the JVM and does not have a direct code example.

Tooling


1. Launch Multi-File Source-Code Programs - JEP 458

  • Technical Explanation: This feature allows the Java launcher to run programs that span multiple source files, simplifying the development and testing process for multi-file programs.
  • Layman Explanation: It makes it easier to run Java programs that are split across several files without needing to compile them first.
  • Refer: Source Oracle Docs

Code Example

Given the files Main.java and Helper.java.

// Main.java
public class Main {
    public static void main(String[] args) {
        Helper.greet();
    }
}
// Helper.java
public class Helper {
    static void greet() {
        System.out.println("Hello from Helper!");
    }
}

You can run the program directly with,

java Main.java Helper.java.

Conclusion

JDK 22 introduces a range of features that enhance the language, libraries, performance, and tooling, making Java even more powerful and developer-friendly. Whether you're optimizing performance, simplifying concurrent programming, or leveraging new language features, JDK 22 has something valuable to offer.


Similar Articles