What are sealed classes in Java 17
Today I updated my java version from 16 to 17 and I found that sealed
class is a new feature in it. I think it can be declared like this -
public sealed class Main{
}
But what is the use of sealed classes in java?
I also knew that it was a preview feature in jdk-15
You can follow this link for examples.
In short sealed classes gives you the control of which models, classes etc. that can implement or extend that class/interface.
Example from the link:
public sealed interface Service permits Car, Truck {
int getMaxServiceIntervalInMonths();
default int getMaxDistanceBetweenServicesInKilometers() {
return 100000;
}
}
This interface only permits Car and Truck to implement it.
The JEP 409 explains it as
A sealed class or interface can be extended or implemented only by those classes and interfaces permitted to do so.
A more practical explanation is the following:
The situation in the past was:
- You could not restrict an interface being extended by another interface
- You could not constraint which classes where able to implement a specific interface.
- You had to declare a class as final in order to not be extended by another class. This way no class could extend the declared final class. This was black or white approach.
The current situation with sealed keyword is:
-
You can now restrict an interface being extended by other interfaces and make a rule for only some specific interfaces which will be allowed to extend it.
Example:
public sealed interface MotherInterface permits ChildInterfacePermitted {} //Has to be declared either as sealed or non-sealed public non-sealed interface ChildInterfacePermitted extends MotherInterface {} public interface AnotherChildInterface extends MotherInterface {} //compiler error! It is not included in the permits of mother inteface
-
You can now create an interface and select only specific classes that are allowed to implement that interface. All other classes are not allowed to implement it.
Example:
public sealed interface MotherInterface permits ImplementationClass1 {} //Has to be declared either as final or as sealed or as non-sealed public final class ImplementationClass1 implements MotherInterface {} public class ImplementationClass2 implements MotherInterface {} //compiler error! It is not included in the permits of mother inteface
-
You can now restrict a class being extended (same as before with final) but you can now allow some specific classes to extend it. So now you have more control as before the keyword final was absolute restricting every class from extending the declared final class
Example:
public sealed class MotherClass permits ChildClass1 {} //Has to be declared either as final or as sealed or as non-sealed public non-sealed class ChildClass1 extends MotherClass {} public class ChildClass2 extends MotherClass {} //compiler error! It is not included in the permits of MotherClass
Important notes:
-
The sealed class and its permitted subclasses must belong to the same module, and, if declared in an unnamed module, to the same package.
Example:
Let's say that we have the same unnamed module and the following packages
-packageA -Implementationclass1.java -packageB -MotherClass.java
or
-root -MotherClass.java -packageA -Implementationclass1.java
You will get the error Class is not allowed to extend sealed class from another package. So if you have an unnamed module all participating classes and interfaces for the sealed function must be placed exactly on the same package.
-
Every permitted subclass must directly extend the sealed class.