What is the purpose of the sealed keyword in Java?

Table of Contents

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.

Similar Questions