Skip to main content

Command Palette

Search for a command to run...

Sealed classes in Java

Published
•3 min read•View as Markdown
Sealed classes in Java
H

I am a developer from Hyderabad India. I am new to writing blogs having started this blog in April 2023. I will be writing mostly on java, spring, spring boot as well as language agnostic topics like algorithms, DB, how things work under the hood etc.

Java as a language has always supported reusability of code, be it through Association(Has-A-relation) or Inheritance(Is-A-relation).

But, do we always need reusability ?? Imagine a class DomesticAnimal, and it has some cool methods that are only applicable to animals that can be domesticated like cats or dogs. What if someone creates a Lion class that inherits DomesticAnimal?

One solution is to make DomesticAnimal final so that Lion class can't misuse it, but then our Cat and Dog classes can't use/inherit it.

Before Java-17, we didn't have solution to this type of scenario, in Java-17 the concept of a sealed class was introduced where a class can declare which all classes can inherit it. In our example above, DomesticAnimal can declare that only Cat and Dog classes can inherit it.

public sealed class DomesticAnimal permits Cat,Dog{
}

Here in the example above we can see that DomesticAnimal is permitting cat and Dog classes.

Now we can declare our Cat and Dog classes, as below:

public non-sealed class Cat extends DomesticAnimal {
}
public final class Dog extends DomesticAnimal {
}

Here if we see carefully, we can see that in the child class, we are using the modifier final or non-sealed. This is due to the reason that if we are inheriting a sealed class, we have to explicitly tell that the child class will either be final(No further inheritance), sealed(inheritance with restrictions) or non-sealed(full inheritance).

That's it..!!! That's how we use sealed classes in Java.

Now there are some constraints as well while using sealed classes, they are mentioned below:

  • Every permitted subclass must explicitly extend the sealed class.

  • Every permitted subclass must define a modifier: final, sealed, or non-sealed.

  • All permitted subclasses must belong to the same module as the sealed class.

To support sealed classes, two changes were made in reflection API, where two public methods have been added to the java.lang.Class:

  • isSealed method, returns true if this 'class' is a sealed class or interface

  • getPermittedSubclasses method, if it is a sealed class, returns an array containing subclasses permitted to extend or implement this class or interface

Sample program to see sealed class example in Java-17 and above.

package org.example;

import java.lang.constant.ClassDesc;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class Main {

    public static void main(String[] args) {

        System.out.println("DomesticAnimal is sealed: " +
                DomesticAnimal.class.isSealed());
        for (Class<?> cd : DomesticAnimal.class.getPermittedSubclasses())
        {
            System.out.println(cd);
        }
    }
}

The output for the above program will be as below:

DomesticAnimal is sealed: true

class org.example.Cat

class org.example.Dog

Process finished with exit code 0


That's all for this blog. Thanks for reading this article. I hope you learned something new today.

If you did, please like/share so that it reaches others as well.