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 finalfield declarations- A constructor
- Getter methods
- Overrides for
toString(),equals(), andhashCode()
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.