Location>code7788 >text

New features of Java 21

Popularity:286 ℃/2025-04-13 22:24:46

Java 21 is an important update of the Java language, introducing several new features to improve developers' programming efficiency and code quality. This article will introduce in detail the new features of Java 21, including basic concepts, usage methods, common practices, and best practices.

 

Introduction

With the continuous evolution of the Java language, Java 21 has made many improvements in syntax, performance and concurrency models. This update emphasizes code readability and simplicity, while improving the ability of parallel programming. New features help developers better apply modern programming concepts.

Java 21 new features overview

Java 21 brings a range of enhancements, including but not limited to:

  1. Pattern matching enhancement
  2. Sealing class extension
  3. Recording mode
  4. Structured concurrency
  5. Virtual thread

Pattern matching enhancement

Pattern matching is becoming increasingly important in Java, and this pattern has greatly enhanced the expression ability of the Java language. In Java 21, pattern matching is not limited to instanceof, but alsoswitchNew ability to express expressions.

Object obj = getObject();
switch (obj) {
    case Integer i -> ("Integer: " + i);
    case String s -> ("String: " + s);
    default -> ("Unknown type");
}

It can be simplified by switch expressions. Replace colon (:) with arrow (->), and the switch expression does not fail by default, so break is not required.

private static void withSwitchExpression(Fruit fruit) {
     switch (fruit) {
         case APPLE, PEAR -> ("ordinary fruit");
         case MANGO, AVOCADO -> ("Imported Fruit");
         default -> ("Unknown fruit");
     }
 }

The switch expression can also return a value. For example, in the above example, we can ask the switch to return a string to represent the text we want to print. It is necessary to note that you need to add a semicolon at the end of the switch statement.

private static void withReturnValue(Fruit fruit) {
     String text = switch (fruit) {
         case APPLE, PEAR -> "Ordinary Fruit";
         case MANGO, AVOCADO -> "Imported Fruit";
         default -> "Unknown fruit";
     };
     (text);
 }

You can also directly omit the assignment action and print it directly.

private static void withReturnValue(Fruit fruit) {
     (switch (fruit) {
         case APPLE, PEAR -> "Ordinary Fruit";
         case MANGO, AVOCADO -> "Imported Fruit";
         default -> "Unknown fruit";
     });
 }

If you want to do more than one thing in the case, such as performing some calculations or printing operations before returning, you can use braces as case blocks, and the last return value is returned using the keyword yield.

private static void withYield(Fruit fruit) {
     String text = switch (fruit) {
         case APPLE, PEAR -> {
             ("The fruit given is: " + fruit);
             yield "ordinary fruit";
         }
         case MANGO, AVOCADO -> "Imported Fruit";
         default -> "Unknown fruit";
     };
     (text);
 }

Of course, you can also use yield to return the result directly.

private static void oldStyleWithYield(Fruit fruit) {
     (switch (fruit) {
         case APPLE, PEAR:
             yield "ordinary fruit";
         case MANGO, AVOCADO:
             yield "imported fruit";
         default:
             yield "unknown fruit";
     });
 }

How to use

The introduced pattern matching allowsswitchMore complex matching and operations are performed in statements. The writing is concise and improves readability.

Common practices

Using pattern matching can often be used to parse complex object structures and enhance code flexibility.

Best Practices

  • Use pattern matching instead of multiple if-else judgments, and declare break returns.
  • Avoid too deep nesting.

Sealing class extension

Seal classes are supported more in Java 21, allowing developers to granularly control the inheritance structure.

public sealed class Shape permits Circle, Rectangle {
    //...
}
public final class Circle extends Shape {
    //...
}

How to use

Sealed classes allow explicitly specifying which subclasses can inherit it in the class declaration, helping to control the class's hierarchy.

Common practices

Suitable for business scenarios that require strict control of subclass collections, such as geometry, syntax trees and other advanced structures.

Best Practices

  • Matchsealednon-sealedandfinalKeyword usage enhances the readability of class hierarchy.
  • A well-defined and stable collection of subclasses.

Recording mode

Recording mode provides a way to concisely define unchanged data carrying classes and supports schema parsing.

record Point(int x, int y) {}

Point p = new Point(3, 4);
("Point: " + () + ", " + ());

How to use

The record class automatically generates accessors, equals(), hashCode(), and toString() methods for all fields, without manual definition.

Common practices

Simple object storage for data transfer, avoiding duplicate code.

Best Practices

  • Suitable for situations where immutable data is required.
  • Recording class fields should be designed as private and ultimately as possible, maintaining their immutable properties.

Structured concurrency

Java 21 introduces structured concurrency, simplifies complex concurrent structures and improves the maintainability of code.

try (var executor = ()) {
    Future<Integer> future1 = (() -> heavyComputation1());
    Future<Integer> future2 = (() -> heavyComputation2());

    Integer result1 = ();
    Integer result2 = ();
    ("Results: " + result1 + ", " + result2);
}

How to use

Through structured concurrency, developers can start, manage, and end multiple concurrent tasks within one context.

Common practices

Applied to task processing that requires concurrent execution, such as parallel data processing and batch calculation.

Best Practices

  • Rationally design concurrency boundaries to ensure effective allocation and recycling of thread resources.
  • Use try-with-resources to ensure automatic closing of the collection.

Virtual thread

Virtual threading is a revolutionary advance brought about by Java 21, allowing large-scale lightweight threading operations to go beyond the limitations of traditional threads.

(() -> {
    ("Running in a virtual thread");
});

How to use

Virtual threads are created to efficiently handle I/O-intensive applications.

Common practices

Especially suitable for high concurrency and I/O heavy application scenarios, such as web server requests.

Best Practices

  • Use virtual threads as the default concurrency model to reduce blocking operations.
  • Combined use of structured concurrency further enhances the flexibility of the model.

summary

Java 21 provides developers with many new features, from language structure to concurrency models, improving the efficiency of development and the simplicity of code. By learning these new features, developers can write more expressive and maintainable code, and they should reasonably choose application scenarios based on specific needs.

References

  • OpenJDK official website
  • Java 21 official release notes
  • Java Mangazine
  • Technology stack website