Java tutorials > Modern Java Features > Java 8 and Later > What are sealed classes (Java 17)?
What are sealed classes (Java 17)?
Sealed classes, introduced in Java 17, offer a powerful way to control the inheritance hierarchy of a class or interface. They allow you to explicitly define which classes are permitted to extend or implement a sealed class or interface, preventing any other classes from doing so. This feature enhances code security, maintainability, and readability by restricting the possible subclasses, making reasoning about the code easier.
Basic Syntax and Example
This example defines a sealed class `Shape`. The `permits` keyword specifies that only `Circle`, `Rectangle` and `Square` classes can extend `Shape`. Any other class attempting to extend `Shape` will result in a compile-time error. Notice that subclasses must be `final`, `sealed`, or `non-sealed`. `final` prevents further inheritance, `sealed` continues to restrict inheritance, and `non-sealed` opens the class to unrestricted inheritance (use with caution).
sealed class Shape permits Circle, Rectangle, Square {
// Common properties and methods for all shapes
}
final class Circle extends Shape {
// Circle-specific implementation
}
final class Rectangle extends Shape {
// Rectangle-specific implementation
}
final class Square extends Rectangle{
// Square-specific implementation
}
Concepts Behind the Snippet
The core concept behind sealed classes is controlled inheritance. Traditional inheritance allows any class to extend another, potentially leading to unexpected behavior or security vulnerabilities. Sealed classes enforce a strict contract by explicitly listing the permitted subclasses. This offers increased type safety, predictability, and better code organization.
Real-Life Use Case Section
Consider a scenario where you're developing an API for handling payment methods. You might want to define a sealed class `PaymentMethod` with permitted subclasses like `CreditCardPayment`, `PayPalPayment`, and `BankTransferPayment`. By sealing the `PaymentMethod` class, you prevent external developers from adding unauthorized payment methods, ensuring the integrity and security of your payment processing system. Another case is in modeling a closed set of states in a state machine. Sealed classes make it easier to ensure that all possible states are handled, improving code robustness.
Best Practices
Interview Tip
When discussing sealed classes in an interview, emphasize their role in controlling inheritance, improving type safety, and enhancing code maintainability. Be prepared to explain the `permits` clause and the requirements for subclasses of sealed classes (i.e., they must be `final`, `sealed`, or `non-sealed`). Also be ready to discuss potential use cases and the tradeoffs involved in using sealed classes versus other inheritance strategies.
When to Use Them
Use sealed classes when:
Memory Footprint
Sealed classes themselves don't inherently introduce significant memory overhead. The memory footprint is primarily determined by the properties and methods defined within the sealed class and its permitted subclasses. The JVM's optimizations can often minimize any potential overhead associated with the sealed nature of the classes.
Alternatives
Before Java 17, you could achieve similar (but less strict) control over inheritance using:
Sealed classes provide a more robust and explicit solution for controlling inheritance than these older techniques.
Pros
Cons
FAQ
-
What happens if I try to extend a sealed class without being permitted?
You will get a compile-time error. The compiler will enforce the `permits` clause and prevent any unauthorized classes from extending the sealed class. -
Can a permitted subclass be abstract?
Yes, a permitted subclass can be abstract. However, any non-abstract subclass must be `final`, `sealed`, or `non-sealed`. -
Are sealed classes applicable to interfaces?
Yes, the `sealed` keyword can also be applied to interfaces. The `permits` clause then specifies the permitted implementing classes. -
What does `non-sealed` mean?
When a subclass of a sealed class is declared as `non-sealed`, it removes the inheritance restriction, allowing any other class to extend it. Use it with caution because you lose the control that the sealed class provides.