What is the purpose of the sealed keyword in Java?
Table of Contents
- Introduction
- Purpose of the
sealed
Keyword - Rules for Using the
sealed
Keyword - Practical Examples of Sealed Classes
- Conclusion
Introduction
The sealed
keyword, introduced in Java 17, allows developers to control and restrict which classes or interfaces can extend or implement a particular class or interface. This feature improves the maintainability, security, and clarity of class hierarchies by limiting the extension to specific subclasses. In this article, we’ll discuss the purpose of the sealed
keyword, its usage, and how it enhances object-oriented programming in Java.
Purpose of the sealed
Keyword
1. Restricting Inheritance
The sealed
keyword restricts which classes or interfaces can extend a given class or implement a given interface. When a class is declared as sealed, only a defined set of classes can inherit from it. This allows developers to limit the flexibility of subclassing, ensuring that only certain, pre-approved classes can be part of the inheritance hierarchy.
Example:
In this example, the Shape
class is sealed, and only the Circle
and Square
classes are allowed to extend it. No other class can inherit from Shape
, ensuring tight control over the class hierarchy.
2. Improving Security and Maintainability
By restricting which classes can extend a sealed class, you can avoid unexpected modifications or misuse of your API. This leads to better security and easier maintenance. Sealed classes provide a way to precisely define the allowed set of subtypes, which is particularly useful in domain modeling and complex hierarchies.
3. Exhaustive Pattern Matching
Sealed classes are beneficial when used with pattern matching (introduced in Java 17). Since the set of subclasses is known at compile-time, the compiler can ensure that all possible cases are covered when using pattern matching, reducing the chance of runtime errors.
Example:
In this example, because the Shape
class is sealed, we know that only Circle
and Square
can be passed to the describeShape()
method. This allows for exhaustive pattern matching without requiring a default case.
Rules for Using the sealed
Keyword
1. Permitted Subclasses
When a class is sealed, it must explicitly specify the permitted subclasses using the permits
clause. The subclasses can be:
**final**
: A final class cannot be extended further.**non-sealed**
: A non-sealed class removes the restrictions of sealed, allowing further subclassing.**sealed**
: A subclass can itself be sealed, further restricting its own hierarchy.
Example:
In this example, Dog
is final, meaning no other class can extend it, while Cat
is non-sealed, allowing further subclassing.
2. Must Be in the Same Module or Package
The permitted subclasses must reside in the same module or package as the sealed class. This rule ensures that the extension hierarchy is manageable and controlled within a confined scope.
Practical Examples of Sealed Classes
Example 1: Defining a Restricted Class Hierarchy
In this example, we define a sealed Vehicle
class and restrict inheritance to specific subclasses:
Here, only Car
and Bike
can extend Vehicle
. Any attempt to create another subclass will result in a compile-time error.
Example 2: Combining Sealed Classes with Non-Sealed Subclasses
In this scenario, CreditCard
is final, while PayPal
is non-sealed, meaning future developers can create more classes that extend PayPal
.
Conclusion
The sealed
keyword in Java provides a powerful mechanism to control class inheritance, ensuring that only permitted subclasses can extend a class or interface. This feature improves code security, maintainability, and clarity by enforcing restrictions on class hierarchies. Sealed classes also work well with Java's pattern matching, allowing for exhaustive and predictable type checking. By leveraging this feature, developers can create well-structured and secure systems, especially in complex projects.