Java 17 Improvements: Sealed Classes, Records, and More

Java 17 is the latest major release of the Java programming language. It comes with many new features and improvements to make programming more efficient and enjoyable. In this post, we'll take a closer look at some of the most important additions to Java 17: sealed classes and interfaces, pattern matching for instanceof, enhanced switch expressions, and records.

Sealed Classes and Interfaces

Sealed classes and interfaces restrict the classes that can extend or implement them. This provides better control over class hierarchies and improves encapsulation. Prior to Java 17, developers could only use the final keyword to prevent class extension. However, the final keyword was too restrictive, as it didn't allow for any extension at all. Sealed classes and interfaces offer a more flexible solution.

Records

Records are a new kind of class that allow developers to define simple classes with a concise syntax. They include built-in methods for equality, hash code, and toString. This makes it easier to define classes that are mainly used for holding data. Prior to Java 17, developers had to define these methods manually, which could be a time-consuming process.

Before:

public class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

After:

public record Person(String name, int age) {}

Pattern Matching for instanceof

Pattern matching for instanceof is a new feature that enables developers to match the type of an object in a switch statement or an if statement without having to cast it explicitly.

Before

if (shape instanceof Circle) {
  Circle circle = (Circle) shape;
  // Do something with the circle
}

After

if (shape instanceof Circle circle) {
  // Do something with the circle
}

This allows developers to match the type of an object in a more concise and efficient way, without having to cast it explicitly.

Enhanced Switch Expressions

Before:

int dayOfWeek = 3;
String dayName;
switch (dayOfWeek) {
  case 1:
    dayName = "Monday";
    break;
  case 2:
    dayName = "Tuesday";
    break;
  case 3:
    dayName = "Wednesday";
    break;
  // ...
  default:
    dayName = "Invalid day";
    break;
}

After:

int dayOfWeek = 3;
String dayName = switch (dayOfWeek) {
  case 1 -> "Monday";
  case 2 -> "Tuesday";
  case 3 -> "Wednesday";
  // ...
  default -> "Invalid day";
};

The enhanced switch expression syntax has been extended to allow more concise and flexible patterns and provide better compatibility with pattern matching for instanceof.