Quick Summary:
- Lets classes and interfaces restrict their subtypes, ensuring more predictable and maintainable code by controlling inheritance explicitly.
- Released in Java 17 (2021), but introduced in Java 15 (2021).
Key Features
- Controlled Extensibility: Sealed classes can define their allowed subtypes, which restricts how they can be extended or implemented, preventing unintended usage and enhancing encapsulation.
- Comprehensive Type System: Works together with records (JEP 395) and pattern matching (JEP 394) to create a more robust and expressive type system.
- Improved Maintainability: Helps to clearly communicate the design intention of the code and ensures that all subclasses are known and located in a controlled fashion.
Example
Before Java 17:
Without sealed classes, any class could extend another class if it wasn’t declared as final
, leading to potentially unpredictable subclassing.
public abstract class Shape {
// Class body omitted for brevity
public abstract double calcArea();
public class Circle extends Shape {
public class Triangle extends Shape {
// Triangle implementation
public class Square extends Shape {
public class FooBarShape extends Shape {
public double calcArea() {
return -Math.sqrt(2); //
Problematic uncontrolled subclass with potential for bugs and inconsistencies public abstract class Shape {
// Class body omitted for brevity
public abstract double calcArea();
}
public class Circle extends Shape {
// Circle implementation
}
public class Triangle extends Shape {
// Triangle implementation
}
public class Square extends Shape {
// Square implementation
}
public class FooBarShape extends Shape {
@Override
public double calcArea() {
return -Math.sqrt(2); //

Problematic uncontrolled subclass with potential for bugs and inconsistencies
}
}
public abstract class Shape {
// Class body omitted for brevity
public abstract double calcArea();
}
public class Circle extends Shape {
// Circle implementation
}
public class Triangle extends Shape {
// Triangle implementation
}
public class Square extends Shape {
// Square implementation
}
public class FooBarShape extends Shape {
@Override
public double calcArea() {
return -Math.sqrt(2); //
Problematic uncontrolled subclass with potential for bugs and inconsistencies
}
}
After Java 17:
With sealed classes you can strictly specify your hierarchy from the superclass.
public sealed abstract class Shape permits Circle, Square, Triangle {
// Class body omitted for brevity
public abstract double calcArea();
public final class Circle extends Shape {
public final class Triangle extends Shape {
// Triangle implementation
public final class Square extends Shape {
public class FooBarShape extends Shape { //
'FooBarShape' is not allowed in the sealed hierarchy // Problematic implementation avoided 
public sealed abstract class Shape permits Circle, Square, Triangle {
// Class body omitted for brevity
public abstract double calcArea();
}
public final class Circle extends Shape {
// Circle implementation
}
public final class Triangle extends Shape {
// Triangle implementation
}
public final class Square extends Shape {
// Square implementation
}
public class FooBarShape extends Shape { //

'FooBarShape' is not allowed in the sealed hierarchy
// Problematic implementation avoided

}
public sealed abstract class Shape permits Circle, Square, Triangle {
// Class body omitted for brevity
public abstract double calcArea();
}
public final class Circle extends Shape {
// Circle implementation
}
public final class Triangle extends Shape {
// Triangle implementation
}
public final class Square extends Shape {
// Square implementation
}
public class FooBarShape extends Shape { //
'FooBarShape' is not allowed in the sealed hierarchy
// Problematic implementation avoided
}
- In this setup,
Shape
is a sealed class that explicitly permits Circle
, Triangle
and Square
as its direct subclasses.
Circle
, Triangle
and Square
are all final
classes, meaning they cannot be subclassed further.
FooBarShape
, having not been explicitly permitted by the sealed class Shape
, causes a compilation error as it’s trying to inherit a sealed class without permission.
Creating Sealed Classes
Making a sealed class involves adding some keywords to your normal class/record declaration:
- Declare the sealed type: Use keyword
sealed
.
- Declare the permitted subtypes: Follow the name up with keyword
permits
followed by a comma-separated list of subtypes.
public sealed abstract class Shape permits Circle, Square, Triangle {
public sealed abstract class Shape permits Circle, Square, Triangle {
public sealed abstract class Shape permits Circle, Square, Triangle {
Hands-on Demo: Sealed Classes
Click here to expand
1. Multiple Choice Quiz
What is the primary purpose of introducing sealed classes in Java?
A) To allow classes to be sealed against modification
B) To restrict which other classes or interfaces may extend or implement them
C) To automatically seal all methods within a class
D) To integrate better with Java’s reflection APIs
2. Fill-in-the-Blanks
- Fill in the blanks to correctly declare a sealed class and its permitted subclasses in Java.
______ sealed class Vehicle ______ Car, Truck {
______ class Car extends Vehicle {
final class Truck extends Vehicle {
______ sealed class Vehicle ______ Car, Truck {
}
______ class Car extends Vehicle {
}
final class Truck extends Vehicle {
}
______ sealed class Vehicle ______ Car, Truck {
}
______ class Car extends Vehicle {
}
final class Truck extends Vehicle {
}
3. Debugging Challenge: Code Correction
Below is an attempt to define a sealed class hierarchy in Java. However, the code contains several mistakes. Identify and correct them so that the code compiles successfully.
public sealed interface Animal permits Cat, Dog {
class Cat extends Animal { // Error here
public void makeSound() {
System.out.println("Meow");
class Dog implements Animal { // Error here
public void makeSound() {
System.out.println("Bark");
public sealed interface Animal permits Cat, Dog {
void makeSound();
}
class Cat extends Animal { // Error here
public void makeSound() {
System.out.println("Meow");
}
}
class Dog implements Animal { // Error here
public void makeSound() {
System.out.println("Bark");
}
}
public sealed interface Animal permits Cat, Dog {
void makeSound();
}
class Cat extends Animal { // Error here
public void makeSound() {
System.out.println("Meow");
}
}
class Dog implements Animal { // Error here
public void makeSound() {
System.out.println("Bark");
}
}
4. Vehicles
- Create a new abstract
Vehicle
-class that contains some basic fields (e.g. colour
, movementSpeed
, etc.) and abstract method (e.g. move()
).
- Create 2 subclasses
Car
(which has an extra breakHorsePower
field) and Bicycle
(with a nrOfGears
field), each of which provides its own implementation of move()
.
- Restrict the subtyping of
Vehicle
to just those two subclasses you just made.
- Double-check that you’ve made the subclasses
final
so that it can still compile.
- Create another subclass,
Airplane
, that also inherits Vehicle
. What happens? Why?
- In a
VehiclesApp
-class, in the main
-method, make a list of 3 vehicles (polymorphism).
Solutions
Click here to reveal the solutions
1. Multiple Choice Quiz
Answer: B) To restrict which other classes or interfaces may extend or implement them
2. Fill-in-the-Blanks
______ sealed class Vehicle ______ Car, Truck {
______ class Car extends Vehicle {
final class Truck extends Vehicle {
______ sealed class Vehicle ______ Car, Truck {
}
______ class Car extends Vehicle {
}
final class Truck extends Vehicle {
}
______ sealed class Vehicle ______ Car, Truck {
}
______ class Car extends Vehicle {
}
final class Truck extends Vehicle {
}
public sealed class Vehicle permits Car, Truck {
final class Car extends Vehicle {
final class Truck extends Vehicle {
public sealed class Vehicle permits Car, Truck {
}
final class Car extends Vehicle {
}
final class Truck extends Vehicle {
}
public sealed class Vehicle permits Car, Truck {
}
final class Car extends Vehicle {
}
final class Truck extends Vehicle {
}
3. Debugging Challenge: Code Correction
Original:
public sealed interface Animal permits Cat, Dog {
class Cat extends Animal { // Error here
public void makeSound() {
System.out.println("Meow");
class Dog implements Animal { // Error here
public void makeSound() {
System.out.println("Bark");
public sealed interface Animal permits Cat, Dog {
void makeSound();
}
class Cat extends Animal { // Error here
public void makeSound() {
System.out.println("Meow");
}
}
class Dog implements Animal { // Error here
public void makeSound() {
System.out.println("Bark");
}
}
public sealed interface Animal permits Cat, Dog {
void makeSound();
}
class Cat extends Animal { // Error here
public void makeSound() {
System.out.println("Meow");
}
}
class Dog implements Animal { // Error here
public void makeSound() {
System.out.println("Bark");
}
}
Corrected:
public sealed interface Animal permits Cat, Dog {
final class Cat implements Animal { // Corrected: 'implements' used, and class marked as 'final'
public void makeSound() {
System.out.println("Meow");
final class Dog implements Animal { // Corrected: class marked as 'final'
public void makeSound() {
System.out.println("Bark");
public sealed interface Animal permits Cat, Dog {
void makeSound();
}
final class Cat implements Animal { // Corrected: 'implements' used, and class marked as 'final'
public void makeSound() {
System.out.println("Meow");
}
}
final class Dog implements Animal { // Corrected: class marked as 'final'
public void makeSound() {
System.out.println("Bark");
}
}
public sealed interface Animal permits Cat, Dog {
void makeSound();
}
final class Cat implements Animal { // Corrected: 'implements' used, and class marked as 'final'
public void makeSound() {
System.out.println("Meow");
}
}
final class Dog implements Animal { // Corrected: class marked as 'final'
public void makeSound() {
System.out.println("Bark");
}
}
Explanation:
- The keyword
implements
should be used instead of extends
for interfaces.
- The
Cat
-class and Dog
-class must be declared with final
or another subclass-specific modifier to align with the sealed contract unless it is intended to be non-sealed
, but then it would need to be explicitly stated.
4. Vehicles
public abstract sealed class Vehicle permits Car, Bicycle {
private double movementSpeed;
public Vehicle(String colour) {
public String getColour() {
public void setColour(String colour) {
public double getMovementSpeed() {
public void setMovementSpeed(double movementSpeed) {
this.movementSpeed = movementSpeed;
public abstract void move();
public abstract sealed class Vehicle permits Car, Bicycle {
private String colour;
private double movementSpeed;
public Vehicle(String colour) {
this.colour = colour;
}
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public double getMovementSpeed() {
return movementSpeed;
}
public void setMovementSpeed(double movementSpeed) {
this.movementSpeed = movementSpeed;
}
public abstract void move();
}
public abstract sealed class Vehicle permits Car, Bicycle {
private String colour;
private double movementSpeed;
public Vehicle(String colour) {
this.colour = colour;
}
public String getColour() {
return colour;
}
public void setColour(String colour) {
this.colour = colour;
}
public double getMovementSpeed() {
return movementSpeed;
}
public void setMovementSpeed(double movementSpeed) {
this.movementSpeed = movementSpeed;
}
public abstract void move();
}
public final class Car extends Vehicle {
private double breakHorsePower;
public Car(String colour, double breakHorsePower) {
this.breakHorsePower = breakHorsePower;
System.out.printf("The %s car is moving at %f km/h with a break horse power of %f kW%n",
getColour(), getMovementSpeed(), breakHorsePower);
public final class Car extends Vehicle {
private double breakHorsePower;
public Car(String colour, double breakHorsePower) {
super(colour);
this.breakHorsePower = breakHorsePower;
}
@Override
public void move() {
System.out.printf("The %s car is moving at %f km/h with a break horse power of %f kW%n",
getColour(), getMovementSpeed(), breakHorsePower);
}
}
public final class Car extends Vehicle {
private double breakHorsePower;
public Car(String colour, double breakHorsePower) {
super(colour);
this.breakHorsePower = breakHorsePower;
}
@Override
public void move() {
System.out.printf("The %s car is moving at %f km/h with a break horse power of %f kW%n",
getColour(), getMovementSpeed(), breakHorsePower);
}
}
public final class Bicycle extends Vehicle {
public Bicycle(String colour, int nrOfGears) {
this.nrOfGears = nrOfGears;
public int getNrOfGears() {
public void setNrOfGears(int nrOfGears) {
this.nrOfGears = nrOfGears;
System.out.printf("The %s bike is moving at %f km/h%n", getColour(), getMovementSpeed());
public final class Bicycle extends Vehicle {
private int nrOfGears;
public Bicycle(String colour, int nrOfGears) {
super(colour);
this.nrOfGears = nrOfGears;
}
public int getNrOfGears() {
return nrOfGears;
}
public void setNrOfGears(int nrOfGears) {
this.nrOfGears = nrOfGears;
}
@Override
public void move() {
System.out.printf("The %s bike is moving at %f km/h%n", getColour(), getMovementSpeed());
}
}
public final class Bicycle extends Vehicle {
private int nrOfGears;
public Bicycle(String colour, int nrOfGears) {
super(colour);
this.nrOfGears = nrOfGears;
}
public int getNrOfGears() {
return nrOfGears;
}
public void setNrOfGears(int nrOfGears) {
this.nrOfGears = nrOfGears;
}
@Override
public void move() {
System.out.printf("The %s bike is moving at %f km/h%n", getColour(), getMovementSpeed());
}
}
public class Airplane extends Vehicle { //
'Airplane' is not allowed in the sealed hierarchy // Class body omitted for brevity
public class Airplane extends Vehicle { //

'Airplane' is not allowed in the sealed hierarchy
// Class body omitted for brevity
}
public class Airplane extends Vehicle { //
'Airplane' is not allowed in the sealed hierarchy
// Class body omitted for brevity
}
public class VehiclesApp {
public static void main(String[] args) {
List<Vehicle> vehicles = List.of(
public class VehiclesApp {
public static void main(String[] args) {
List<Vehicle> vehicles = List.of(
new Car("red", 100.0),
new Bicycle("blue", 2),
new Car("green", 120.0),
new Bicycle("yellow", 4)
);
}
}
public class VehiclesApp {
public static void main(String[] args) {
List<Vehicle> vehicles = List.of(
new Car("red", 100.0),
new Bicycle("blue", 2),
new Car("green", 120.0),
new Bicycle("yellow", 4)
);
}
}
The non-sealed
Keyword
- The introduction of sealed classes in Java also brought about the
non-sealed
keyword.
- This keyword allows classes within a sealed hierarchy to opt-out of the restrictions imposed by sealing.
- It gives developers the control to define an inheritance chain that is partially closed and partially open, offering a balance between strict encapsulation and flexibility.
Example
public sealed class Shape permits Circle, Rectangle {
// Common methods for shapes
final class Circle extends Shape {
// Circle-specific methods; no further subclassing allowed
non-sealed class Rectangle extends Shape {
// Rectangle-specific methods; subclassing is allowed
// This subclassing is permissible because Rectangle is non-sealed
class Square extends Rectangle {
// Further customization specific to squares
public sealed class Shape permits Circle, Rectangle {
// Common methods for shapes
}
final class Circle extends Shape {
// Circle-specific methods; no further subclassing allowed
}
non-sealed class Rectangle extends Shape {
// Rectangle-specific methods; subclassing is allowed
}
// This subclassing is permissible because Rectangle is non-sealed
class Square extends Rectangle {
// Further customization specific to squares
}
public sealed class Shape permits Circle, Rectangle {
// Common methods for shapes
}
final class Circle extends Shape {
// Circle-specific methods; no further subclassing allowed
}
non-sealed class Rectangle extends Shape {
// Rectangle-specific methods; subclassing is allowed
}
// This subclassing is permissible because Rectangle is non-sealed
class Square extends Rectangle {
// Further customization specific to squares
}
Hands-on Demo: The non-sealed
Keyword
Click here to expand
1. Vehicles (part II)
- Adapt your
Car
-class so that it is no longer final
but still part of the sealed hierarchy.
- Create 2 new subclasses for
Car
, the ElectricCar
-class and the CombustibleEngineCar
-class.
- Update your list of vehicles in
VehiclesApp
to include objects of your 2 new subclasses.
Solutions
Click here to reveal the solutions
1. Vehicles (part II)
public non-sealed class Car extends Vehicle {
private double breakHorsePower;
public Car(String colour, double breakHorsePower) {
this.breakHorsePower = breakHorsePower;
System.out.printf("The %s car is moving at %f km/h with a break horse power of %f kW%n",
getColour(), getMovementSpeed(), breakHorsePower);
public non-sealed class Car extends Vehicle {
private double breakHorsePower;
public Car(String colour, double breakHorsePower) {
super(colour);
this.breakHorsePower = breakHorsePower;
}
@Override
public void move() {
System.out.printf("The %s car is moving at %f km/h with a break horse power of %f kW%n",
getColour(), getMovementSpeed(), breakHorsePower);
}
}
public non-sealed class Car extends Vehicle {
private double breakHorsePower;
public Car(String colour, double breakHorsePower) {
super(colour);
this.breakHorsePower = breakHorsePower;
}
@Override
public void move() {
System.out.printf("The %s car is moving at %f km/h with a break horse power of %f kW%n",
getColour(), getMovementSpeed(), breakHorsePower);
}
}
public class ElectricCar extends Car {
public ElectricCar(String colour, double breakHorsePower) {
super(colour, breakHorsePower);
public class ElectricCar extends Car {
public ElectricCar(String colour, double breakHorsePower) {
super(colour, breakHorsePower);
}
}
public class ElectricCar extends Car {
public ElectricCar(String colour, double breakHorsePower) {
super(colour, breakHorsePower);
}
}
public class CombustibleEngineCar extends Car {
public CombustibleEngineCar(String colour, double breakHorsePower) {
super(colour, breakHorsePower);
public class CombustibleEngineCar extends Car {
public CombustibleEngineCar(String colour, double breakHorsePower) {
super(colour, breakHorsePower);
}
}
public class CombustibleEngineCar extends Car {
public CombustibleEngineCar(String colour, double breakHorsePower) {
super(colour, breakHorsePower);
}
}
public class VehiclesApp {
public static void main(String[] args) {
List<Vehicle> vehicles = List.of(
new Bicycle("yellow", 4),
new ElectricCar("purple", 150.0),
new CombustibleEngineCar("orange", 200.0)
public class VehiclesApp {
public static void main(String[] args) {
List<Vehicle> vehicles = List.of(
new Car("red", 100.0),
new Bicycle("blue", 2),
new Car("green", 120.0),
new Bicycle("yellow", 4),
new ElectricCar("purple", 150.0),
new CombustibleEngineCar("orange", 200.0)
);
}
}
public class VehiclesApp {
public static void main(String[] args) {
List<Vehicle> vehicles = List.of(
new Car("red", 100.0),
new Bicycle("blue", 2),
new Car("green", 120.0),
new Bicycle("yellow", 4),
new ElectricCar("purple", 150.0),
new CombustibleEngineCar("orange", 200.0)
);
}
}
Reality Check: Practical Uses of Sealed Classes
Below are some of the most common use cases where sealed classes prove particularly beneficial:
1. Domain Modeling
Sealed classes are excellent for domain-driven design where you need to represent a fixed set of closely related types. They help enforce business rules at the compiler level, ensuring that the domain model remains consistent and valid throughout its lifecycle.
- Example: In a financial application, you might have a sealed class
Transaction
with specific subclasses like Deposit
, Withdrawal
, and Transfer
. This setup ensures that all transactions processed in the system are one of these defined types, and no unexpected transaction types can exist.
Click to view code example
public sealed class Transaction permits Deposit, Withdrawal, Transfer {
// Common transactional logic here
public final class Deposit extends Transaction {
// Specific logic for a deposit
public final class Withdrawal extends Transaction {
// Specific logic for a withdrawal
public non-sealed class Transfer extends Transaction {
// Specific logic for a transfer, allows further subclassing if needed
public sealed class Transaction permits Deposit, Withdrawal, Transfer {
// Common transactional logic here
}
public final class Deposit extends Transaction {
// Specific logic for a deposit
}
public final class Withdrawal extends Transaction {
// Specific logic for a withdrawal
}
public non-sealed class Transfer extends Transaction {
// Specific logic for a transfer, allows further subclassing if needed
}
public sealed class Transaction permits Deposit, Withdrawal, Transfer {
// Common transactional logic here
}
public final class Deposit extends Transaction {
// Specific logic for a deposit
}
public final class Withdrawal extends Transaction {
// Specific logic for a withdrawal
}
public non-sealed class Transfer extends Transaction {
// Specific logic for a transfer, allows further subclassing if needed
}
2. Defining Finite State Machines
In state machine implementations, sealed classes can define a finite number of states and transitions, which helps in managing state transitions explicitly and safely.
- Example: Consider a workflow system where a document can be in states such as
Draft
, Review
, or Published
. Using a sealed class to define these states can ensure that transitions between states are handled cleanly and that all possible states are explicitly known and handled.
Click to view code example
public sealed class DocumentState permits Draft, Review, Published {
// Base methods common to all states
public final class Draft extends DocumentotState {
// Methods specific to the draft state
public final class Review extends DocumentState {
// Methods specific to the review state
public final class Published extends DocumentState {
// Methods specific to the published state
public sealed class DocumentState permits Draft, Review, Published {
// Base methods common to all states
}
public final class Draft extends DocumentotState {
// Methods specific to the draft state
}
public final class Review extends DocumentState {
// Methods specific to the review state
}
public final class Published extends DocumentState {
// Methods specific to the published state
}
public sealed class DocumentState permits Draft, Review, Published {
// Base methods common to all states
}
public final class Draft extends DocumentotState {
// Methods specific to the draft state
}
public final class Review extends DocumentState {
// Methods specific to the review state
}
public final class Published extends DocumentState {
// Methods specific to the published state
}
3.
Spoiler Alert for JDK 21: Compiler-Assisted Pattern Matching
Starting from Java SE 21, sealed classes are particularly useful with pattern matching, as they allow the compiler to guarantee that all possible subtypes are covered in a switch
expression or statement, eliminating the need for a default case. This leads to safer code that is less prone to errors.
- Example: When handling various shapes in a graphic editor, a sealed class
Shape
could have subclasses such as Circle
, Square
, and Rectangle
. Using pattern matching, you can easily and safely compute properties like area or perimeter, with compile-time checking to ensure all types are handled.
Click to view code example
public static void printShapeDetails(Shape shape) {
double area = shape.area();
double perimeter = shape.perimeter();
String details = switch (shape) {
case Circle c -> String.format("Circle with radius %.2f", c.radius);
case Rectangle r -> String.format("Rectangle with length %.2f and width %.2f", r.length, r.width);
case Triangle t -> String.format("Triangle with sides %.2f, %.2f, %.2f", t.a, t.b, t.c);
default -> throw new IllegalStateException("Unexpected shape type: " + shape.getClass());
System.out.printf("%s has an area of %.2f and a perimeter of %.2f%n", details, area, perimeter);
public static void printShapeDetails(Shape shape) {
double area = shape.area();
double perimeter = shape.perimeter();
String details = switch (shape) {
case Circle c -> String.format("Circle with radius %.2f", c.radius);
case Rectangle r -> String.format("Rectangle with length %.2f and width %.2f", r.length, r.width);
case Triangle t -> String.format("Triangle with sides %.2f, %.2f, %.2f", t.a, t.b, t.c);
default -> throw new IllegalStateException("Unexpected shape type: " + shape.getClass());
};
System.out.printf("%s has an area of %.2f and a perimeter of %.2f%n", details, area, perimeter);
}
public static void printShapeDetails(Shape shape) {
double area = shape.area();
double perimeter = shape.perimeter();
String details = switch (shape) {
case Circle c -> String.format("Circle with radius %.2f", c.radius);
case Rectangle r -> String.format("Rectangle with length %.2f and width %.2f", r.length, r.width);
case Triangle t -> String.format("Triangle with sides %.2f, %.2f, %.2f", t.a, t.b, t.c);
default -> throw new IllegalStateException("Unexpected shape type: " + shape.getClass());
};
System.out.printf("%s has an area of %.2f and a perimeter of %.2f%n", details, area, perimeter);
}
4. API Design
When designing APIs, especially libraries or frameworks, sealed classes can be used to restrict how developers interact with the API, guiding them towards correct usage and preventing misuse by limiting subclassing to a known set of classes.
- Example: In a plugin architecture, you might define a sealed class
Plugin
that all plugins must extend. Specific types of plugins can be defined as final classes extending Plugin
, ensuring all plugins adhere to a specific contract while preventing further subclassing.
Click to view code example
public sealed class Plugin permits AudioPlugin, VideoPlugin {
// Common plugin functionality
public final class AudioPlugin extends Plugin {
// Audio-specific plugin functionality
public final class VideoPlugin extends Plugin {
// Video-specific plugin functionality
public sealed class Plugin permits AudioPlugin, VideoPlugin {
// Common plugin functionality
}
public final class AudioPlugin extends Plugin {
// Audio-specific plugin functionality
}
public final class VideoPlugin extends Plugin {
// Video-specific plugin functionality
}
public sealed class Plugin permits AudioPlugin, VideoPlugin {
// Common plugin functionality
}
public final class AudioPlugin extends Plugin {
// Audio-specific plugin functionality
}
public final class VideoPlugin extends Plugin {
// Video-specific plugin functionality
}
5. Ensuring Security and Consistency
Sealed classes enhance security by controlling subclassing, which is crucial in environments where the integrity and consistency of data or behavior are paramount. This can prevent malicious subclassing or inadvertent errors in extending classes in security-sensitive applications.
- Example: In a security framework handling different types of authentication mechanisms, sealed classes can ensure that only allowed authentication types are implemented and handled, preventing the addition of unverified or insecure implementations.
Click to view code example
public sealed class AuthenticationType permits PasswordAuth, TokenAuth {
// Common authentication functionality
public final class PasswordAuth extends AuthenticationType {
// Password authentication logic
public final class TokenAuth extends AuthenticationType {
// Token authentication logic
public sealed class AuthenticationType permits PasswordAuth, TokenAuth {
// Common authentication functionality
}
public final class PasswordAuth extends AuthenticationType {
// Password authentication logic
}
public final class TokenAuth extends AuthenticationType {
// Token authentication logic
}
public sealed class AuthenticationType permits PasswordAuth, TokenAuth {
// Common authentication functionality
}
public final class PasswordAuth extends AuthenticationType {
// Password authentication logic
}
public final class TokenAuth extends AuthenticationType {
// Token authentication logic
}