Skip to main content
Advertisement

12.4 Records and Sealed Classes

Records(introduced as a preview in Java 14, finalized in Java 16) and ** Sealed Classes**(finalized in Java 17) are cornerstone modern Java features that make your code dramatically more concise and safer.

1. Records

When creating a simple class purely to hold data, you traditionally had to manually write ALL of the following:

  • private final field declarations
  • A constructor
  • Getter methods
  • Overrides for toString(), equals(), and hashCode()

Records auto-generate ALL of this from a single line!

// Old approach: data class (extremely verbose)
public class PersonOld {
private final String name;
private final int age;

public PersonOld(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }

@Override
public String toString() {
return "PersonOld[name=" + name + ", age=" + age + "]";
}
// equals(), hashCode() omitted...
}

// Record approach: exactly 1 line!
public record Person(String name, int age) {}
public class RecordExample {
public static void main(String[] args) {
Person p = new Person("Alice", 25);

// Getters are named after the fields directly
System.out.println(p.name()); // Alice
System.out.println(p.age()); // 25

// toString, equals, hashCode provided automatically
System.out.println(p); // Person[name=Alice, age=25]

Person p2 = new Person("Alice", 25);
System.out.println(p.equals(p2)); // true (compares content)
}
}

Records are Immutable data objects. There are no setters — field values cannot be changed after construction. They are ideal for API response data, DTOs (Data Transfer Objects), and similar use cases.

2. Sealed Classes

A Sealed class is a way to explicitly declare "only these specific classes are permitted to extend this class." Use the sealed keyword alongside a permits clause.

// Shape can only be subclassed by Circle, Rectangle, or Triangle!
public sealed class Shape
permits Circle, Rectangle, Triangle {

public abstract double area();
}

// Each subclass must be declared as: final, sealed, or non-sealed
public final class Circle extends Shape {
private final double radius;
public Circle(double radius) { this.radius = radius; }

@Override
public double area() { return Math.PI * radius * radius; }
}

public final class Rectangle extends Shape {
private final double width, height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}

@Override
public double area() { return width * height; }
}

Sealed classes become especially powerful when combined with Pattern Matching in Java 21's switch expressions.

// Java 21 - switch with Pattern Matching
static String describe(Shape shape) {
return switch (shape) {
case Circle c -> "Circle, area: " + c.area();
case Rectangle r -> "Rectangle, area: " + r.area();
default -> "Unknown shape";
};
}

Records and Sealed Classes are hallmark modern Java features that make the language more expressive, safer, and far easier to maintain.

Advertisement