
1. Overview
In this article, we will learn the new feature Sealed classes and interfaces of Java.
Java introduces the Sealed classes and interfaces as a preview feature in JDK 15 (JEP 360) and JDK 16 (JEP 397). Now, finalized the feature in JDK 17 (JEP 409), with no changes from JDK 16.
Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them. It is more of a declarative way to restrict the use of a superclass rather than using access modifiers.
If you want to understand the purpose of Sealed classes and interfaces, proceed with below sections. Otherwise, navigate to this section to get started with sealed classes and interfaces implementation.
2. Code reusability using Java inheritance
Code reusability is one of the fundamental purposes of inheritance.
When you create a new class and there is already a class available with some of the code you need, you would extend the existing class in your new class. By doing so, you can reuse the existing fields and methods of the superclass without having to rewrite them again.
In Java, a class can be final so no other classes can subclass it. If a class is not final, then it is open to all other classes to support code reusability. Doing so would raise data modeling concerns.
3. Limitations of traditional inheritance
A data model is a logical organization of real-world entities (classes) and standardizes how they relate to one another. Assume you want to model the various possibilities that exist for a real-world scenario by defining the required classes and determining how these classes should relate to each other.
Let’s see an example to understand this concept.
Consider our modeling requirement is to create a Direction
enum class and have only a fixed set of values. Let’s take the following Direction
enum class that has a fixed set of constants (NORTH, SOUTH, EAST, WEST). Here, we defined the Direction
enum class and determined what values it can hold.
Also, if you are going to cover all these constants in your switch expression, then you can ignore a default clause:
enum Direction { NORTH, SOUTH, EAST, WEST } Direction direction = Direction.NORTH; switch (direction) { case NORTH: { System.out.println("North"); } case SOUTH: { System.out.println("SOUTH"); } case EAST: { System.out.println("EAST"); } case WEST: { System.out.println("WEST"); } }
Let’s take a similar example in inheritance.
The below NumberSystem
class is open to all classes, so any subclass can extend it. What if you want to restrict this NumberSystem
to a fixed set of subclasses (Binary, Decimal, Octal, and HexaDecimal)?. It means you don’t want any other arbitrary class to extend this NumberSystem
class.
class NumberSystem { ... } final class Binary extends NumberSystem { ... } final class Decimal extends NumberSystem { ... } final class Octal extends NumberSystem { ... } final class HexaDecimal extends NumberSystem { ... }
You can only follow any of the below approaches to restrict the class from being implemented or extended by other classes.
- Make the class
final
, so it has zero subclasses - Make the class or its constructor
package-private
, so it can only have subclasses in the same package
The first approach makes no sense here. The second approach restricts the access to the same package, but doesn’t satisfy all of our data modeling requirements i.e., to restrict the NumberSystem
class to a known set of subclasses (Binary
, Octal
, Decimal
, HexaDecimal
).
Using sealed class, you can achieve it by controlling the subclasses that can extend it and prevent any other arbitrary class from doing so.
4. Benefits of Java sealed classes and interface
The sealed classes and interfaces would be widely accessible but not widely extensible (restricted to a fixed set of subclasses).
Code reusability is still possible but within a closed class hierarchy.
Supports data modeling
5. Sealed classes and interfaces
5.1. Sealed classes
The syntax to define the Java sealed class is:
sealed class <sealed class name> permits <subclass1>, <subclass2>, <subclass3> { }
To seal a superclass, add the sealed
modifier to its declaration as above. After any extends
and implements
clauses, then add the permits
clause. This clause specifies the subclasses that can extend the sealed class.
Let’s take an example with permits clause.
If your subclasses are in different files in the same module or package, then use permits
clause to define the subclasses that may extend the sealed class:
public sealed class NumberSystem permits Binary, Decimal, Octal, HexaDecimal { }
If all of your subclasses are in the same file as the superclass (sealed class), then you can omit permits clause:
package com.tedblob.numbersystem; public sealed class NumberSystem { } final class Binary extends NumberSystem { .. } final class Octal extends NumberSystem { .. } final class HexaDecimal extends NumberSystem { .. } sealed class Decimal extends NumberSystem { .. } final class NonRecurringDecimal extends Decimal {..} final class RecurringDecimal extends Decimal {..}
In the above code, we omitted the permits clause from the sealed class NumberSystem
as all the subclasses that extend
the NumberSystem
are defined in the same file.
5.1.2. Limitations of sealed classes
The permitted subclasses have the following limitations:
- Must be accessible by the sealed class at compile time. For example, the compiler must be able to access all the subclasses
Binary
,Octal
,HexaDecimal
andDecimal
while compiling theNumberSystem
. SinceDecimal
is a sealed class, the compiler also needs access to itsNonRecurringDecimal
andRecurringDecimal
subclasses. - Permitted subclasses must extend the sealed class directly.
- Allowed modifiers:
final
sealed
non-sealed
- They must be in the same module or the same package as the sealed class
5.2. Non-sealed classes
package com.tedblob.numbersystem; public sealed class NumberSystem { } final class Binary extends NumberSystem { .. } final class Octal extends NumberSystem { .. } final class HexaDecimal extends NumberSystem { .. } non-sealed class Decimal extends NumberSystem { .. } final class NonRecurringDecimal extends Decimal {..} final class RecurringDecimal extends Decimal {..}
In the above example, you have permitted only the specified classes (Binary
, Octal
, HexaDecimal
and Decimal
) to extend NumberSystem
.
Consider you want to allow unknown classes to extend the Decimal
subclass. Though, the NumberSystem
root level hierarchy is closed to set of known classes, you can allow the sub hierarchies to be open by using the non-sealed
keyword.
The sealed
and non-sealed
combination allows you to restrict parts of your hierarchy but not all.
In the below diagram, we restricted the root hierarchy of the sealed class NumberSystem
to a known set of subclasses. However, the non-sealed Decimal
class allows any unknown subclass such as RecurringDecimal
to extend it.
So part of the inheritance hierarchy (Decimal
) is open to all classes.

5.3. Sealed interface
There are scenarios where you don’t want the default methods of the interface to be accessible by unknown classes or interfaces. A sealed interface can prevent unknown classes or interfaces from accessing it.
The syntax of the sealed interface is:
sealed interface <sealed interface name> permits <permitted classes or interfaces> { }
Like the Sealed classes, follow the below steps to declare an sealed interface:
- Add the
sealed
modifier before the interface keyword in the interface declaration - After any
extends
clause, add thepermits
clause which specifies the classes that can implement and the interfaces that can extend the sealed the interface
For example, the below Expr
is a sealed interface that permits MathExpr
and NotANumber
classes to implement it. This defaultMethod
will not be accessible by other unknown classes.
sealed interface Expr permits MathExpr, NotANumber { default void defaultMethod() { } } sealed class MathExpr() implements Expr { .. } final class NotANumber implements Expr { .. }
5.4. Difference between a final and a non-sealed class
A final class
A final class has zero subclasses, meaning no other class can extend it.
A non-sealed class
Any class can extend the non-sealed class.
When you mark a class as sealed
, only the permitted subclasses can extend it and can have only these modifiers final
, sealed
or non-sealed
:
- Any unknown subclass can extend the non-sealed class and is open. It just breaks the sealed class effect and doesn’t pass the restriction down the hierarchy.
6. Conclusion
To sum up, we have learned the sealed classes and interfaces of Java.
Pingback: "Mühürlü Class Java CodeGrepper" kodu Cevap - Kod Yanıtları
Pingback: Réponse du code "Java scellé" Réponse - Coder les réponses
Pingback: "Interface scellée Java CodeGepper" Code Réponse - Coder les réponses
Pingback: java sealed class Code Example - java | Horje
Pingback: What are sealed classes in Java 17 - IT Tutorial Point
Pingback: What Are Sealed Classes In Java 17? - Programming Questions And Solutions Blog