Java Tutorial 0/145 lessons ~6 min read Lesson 36

    Java Sealed Classes

    java sealed classes permits final non-sealed sealed interface pattern matching records Java 17

    Course progress0%
    Focus
    29 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Learning Objectives

    After completing this lesson, you will be able to:

    • Understand what Sealed Classes are
    • Learn why Sealed Classes were introduced
    • Differentiate between sealed, non-sealed, and final
    • Restrict class inheritance
    • Create Sealed Interfaces
    • Use permits clause
    • Combine Sealed Classes with Records
    • Use Pattern Matching with Sealed Classes
    • Understand JVM Internals
    • Apply Sealed Classes in Enterprise Applications
    • Follow Best Practices
    • Prepare for Java Interview Questions

    Introduction

    One of the biggest challenges in Object-Oriented Programming is uncontrolled inheritance.

    Consider the following class:

    code
    public class Vehicle {
    }

    Any developer can create:

    code
    class Car extends Vehicle {}
    class Bike extends Vehicle {}
    class Truck extends Vehicle {}
    class Airplane extends Vehicle {}
    class UFO extends Vehicle {}

    Nothing prevents developers from extending Vehicle.

    Sometimes this is desirable.

    However, in enterprise applications, some class hierarchies should remain controlled.

    Examples:

    • Payment Types
    • HTTP Responses
    • Shapes
    • AST (Abstract Syntax Tree)
    • Banking Transactions
    • Compiler Nodes
    • State Machines

    Java 17 introduced Sealed Classes to solve this problem.

    Why Sealed Classes?

    Suppose we are building a payment system.

    Without restrictions

    code
    class Payment {}
    class Cash extends Payment {}
    class Card extends Payment {}
    class Bitcoin extends Payment {}
    class RandomPayment extends Payment {}

    Anyone can create new subclasses.

    Sometimes this breaks business rules.

    Instead

    code
    public sealed class Payment
    permits Cash,
    Card,
    UPI{
    }

    Only approved subclasses are allowed.

    What is a Sealed Class?

    A Sealed Class restricts which classes or interfaces can extend or implement it.

    Syntax

    code
    public sealed class Shape
    permits Circle,
    Rectangle{
    }

    Only:

    • Circle
    • Rectangle

    can extend Shape.

    Java Version

    FeatureVersion
    PreviewJava 15
    Second PreviewJava 16
    StandardJava 17

    Basic Example

    code
    public sealed class Vehicle
    permits Car,
    Bike{
    }

    Allowed

    code
    public final class Car
    extends Vehicle{
    }
    code
    public final class Bike
    extends Vehicle{
    }

    Not Allowed

    code
    class Truck
    extends Vehicle{
    }

    Compilation Error.

    permits Clause

    The permits keyword explicitly lists permitted subclasses.

    code
    public sealed class Animal
    permits Dog,
    Cat,
    Lion{
    }

    Rules

    Every permitted subclass must declare one of the following:

    • final
    • sealed
    • non-sealed

    final Subclass

    Cannot be extended further.

    code
    public final class Dog
    extends Animal{
    }

    Hierarchy

    code
    Animal
    Dog
    (End)

    sealed Subclass

    Can continue restricting inheritance.

    code
    public sealed class Mammal
    extends Animal
    permits Dog,
    Cat{
    }

    non-sealed Subclass

    Removes restrictions.

    code
    public non-sealed class Bird
    extends Animal{
    }

    Now

    code
    class Eagle
    extends Bird{
    }

    is valid.

    Sealed Class Hierarchy

    code
    Animal (sealed)
    ┌──────────────┼──────────────┐
    │ │ │
    Dog(final) Mammal(sealed) Bird(non-sealed)
    ┌──────┴──────┐
    │ │
    Cat Tiger

    Sealed Interfaces

    Interfaces can also be sealed.

    code
    public sealed interface Payment
    permits CardPayment,
    CashPayment{
    }

    Implementation

    code
    public final class CardPayment
    implements Payment{
    }

    Combining Records with Sealed Classes

    One of the most common enterprise use cases.

    code
    public sealed interface Shape
    permits Circle,
    Rectangle{
    }
    code
    public record Circle(
    double radius)
    implements Shape{
    }
    code
    public record Rectangle(
    double width,
    double height)
    implements Shape{
    }

    Records and Sealed Interfaces work together beautifully for immutable domain models.

    Pattern Matching with Sealed Classes

    (Java 21)

    code
    static double area(
    Shape shape){
    return switch(shape){
    case Circle c ->
    Math.PI *
    c.radius() *
    c.radius();
    case Rectangle r ->
    r.width() *
    r.height();
    };
    }

    Since all subclasses are known, the compiler can verify that the switch is exhaustive.

    Reflection with Sealed Classes

    Check whether a class is sealed.

    code
    System.out.println(
    Shape.class.isSealed()
    );

    Output

    code
    true

    Retrieve permitted subclasses.

    code
    Class<?>[] classes =
    Shape.class.getPermittedSubclasses();
    for(Class<?> clazz : classes){
    System.out.println(
    clazz.getSimpleName()
    );
    }

    Sealed Class Internals

    Conceptually

    code
    Shape
    Compiler
    Restricts inheritance
    JVM verifies subclasses

    The JVM enforces the permitted subclass list.

    Sealed Classes vs Final Classes

    FinalSealed
    No subclass allowedSelected subclasses allowed
    Completely closedPartially closed
    One-level restrictionControlled hierarchy

    Sealed Classes vs Abstract Classes

    AbstractSealed
    Anyone may extendOnly permitted classes may extend
    No inheritance restrictionControlled inheritance
    Can be open-endedExplicit hierarchy

    Real-World Example: Payment System

    code
    public sealed interface Payment
    permits
    CardPayment,
    UPIPayment,
    CashPayment{
    }

    Only approved payment implementations are allowed.

    Real-World Example: API Response

    code
    public sealed interface ApiResponse
    permits
    Success,
    Failure{
    }
    code
    public record Success(
    String message)
    implements ApiResponse{
    }
    code
    public record Failure(
    String error)
    implements ApiResponse{
    }

    Real-World Example: Banking

    code
    public sealed class Transaction
    permits
    Deposit,
    Withdrawal,
    Transfer{
    }

    This prevents unauthorized transaction types.

    Spring Boot Use Cases

    Sealed classes are useful for:

    • API response models
    • Domain events
    • Business rule hierarchies
    • CQRS commands
    • Event sourcing
    • Workflow states

    They are less common for JPA entities because entity inheritance is often designed differently.

    Best Practices

    Use Sealed Classes for Closed Hierarchies

    Examples:

    • Shapes
    • Payment Types
    • Commands
    • Events
    • States

    Combine with Records

    Records provide immutable data.

    Sealed interfaces provide controlled inheritance.

    Together they produce concise and type-safe models.

    Prefer Pattern Matching

    Java 21 switch expressions become safer with sealed hierarchies.

    Keep Hierarchies Small

    Avoid deeply nested sealed hierarchies.

    Document the Hierarchy

    Clearly describe why subclasses are restricted.

    Common Mistakes

    Forgetting final, sealed, or non-sealed

    Wrong

    code
    class Dog
    extends Animal{
    }

    Compilation Error.

    Every permitted subclass must declare one of these modifiers.

    Forgetting permits

    The compiler must know the permitted subclasses unless they are declared in the same compilation unit where inference rules apply.

    Using Sealed Classes Everywhere

    Use them only when the hierarchy should be intentionally closed.

    Expecting Runtime Extension

    Sealed classes enforce inheritance restrictions at compile time and runtime.

    Confusing final with sealed

    code
    final
    No subclasses.
    sealed
    Specific subclasses.

    Hands-on Exercise

    Create a Java program that:

    1. Creates a sealed Shape class.
    2. Creates Circle and Rectangle as permitted subclasses.
    3. Creates a sealed interface named Payment.
    4. Implements CardPayment and CashPayment.
    5. Creates a non-sealed subclass.
    6. Creates a final subclass.
    7. Combines Records with a sealed interface.
    8. Uses pattern matching with a switch expression.
    9. Uses Reflection to inspect permitted subclasses.
    10. Builds a small banking transaction hierarchy using sealed classes.

    Summary

    Sealed Classes, introduced as a standard feature in Java 17, allow developers to explicitly control inheritance by specifying which classes or interfaces may extend or implement a type. Together with Records and Pattern Matching, they enable expressive, type-safe, and maintainable domain models. Sealed Classes are particularly valuable for modeling closed business hierarchies such as payments, commands, states, and events in modern enterprise applications.

    Key Takeaways

    • Sealed Classes restrict inheritance.
    • The permits clause lists allowed subclasses.
    • Every permitted subclass must be final, sealed, or non-sealed.
    • Sealed Interfaces work the same way as sealed classes.
    • Records integrate naturally with sealed hierarchies.
    • Pattern Matching becomes exhaustive with sealed types.
    • Reflection can inspect sealed hierarchies.
    • Use Sealed Classes for closed domain models.
    • Do not replace every abstract class with a sealed class.
    • Sealed Classes are a major feature of modern Java (Java 17+).

    Professional Interview Questions

    1What are Sealed Classes in Java?

    Professional Answer

    Sealed Classes are a Java feature introduced as a standard feature in Java 17 that allow developers to explicitly control which classes or interfaces can extend or implement a type. They provide compile-time and runtime enforcement of a closed inheritance hierarchy, making domain models safer and easier to maintain.

    Follow-up Questions

    • Which Java version standardized Sealed Classes?
    • What keyword lists permitted subclasses?

    Interview Tip: Sealed Class = Controlled Inheritance.

    2What is the difference between sealed, final, and non-sealed?

    Professional Answer

    A sealed class restricts inheritance to a predefined set of permitted subclasses. A final class completely prevents further inheritance. A non-sealed class removes the restriction imposed by a sealed superclass, allowing unrestricted subclassing again. Every direct subclass of a sealed class must explicitly declare one of these three modifiers.

    Follow-up Questions

    • Can a sealed class have a non-sealed subclass?
    • Why must every permitted subclass declare one of these modifiers?

    Interview Tip: final → No Children, sealed → Selected Children, non-sealed → Open Again.

    3Why are Sealed Classes useful with Records and Pattern Matching?

    Professional Answer

    Sealed Classes define a closed hierarchy, Records provide concise immutable data carriers, and Pattern Matching enables exhaustive type-safe processing. Together, they allow the compiler to verify that all possible cases are handled, resulting in cleaner, safer, and more maintainable code for business domains such as payments, workflow states, and command processing.

    Follow-up Questions

    • Why can the compiler verify an exhaustive switch over a sealed hierarchy?
    • What enterprise scenarios benefit most from this combination?

    Interview Tip: Records → Immutable Data, Sealed Classes → Controlled Hierarchy, Pattern Matching → Type-Safe Processing.

    Ready to mark this lesson complete?Track your journey across the entire course.