Toll Free:

1800 889 7020

Sealed Classes in Java: Benefits and Syntax Explained

What are Sealed Classes in Java?

Java has consistently offered a comprehensive object-oriented programming architecture that enables programmers to create scalable and reliable systems. However, in large systems, unfettered inheritance can occasionally result in mistakes and unexpected designs. Java 15 introduced sealed classes as a preview feature to allay these worries, and by Java 17, they became a standard feature. By offering a compromise between open inheritance and final classes, which cannot be expanded, sealed classes in Java assist developers in better managing inheritance.

Java 17 Sealed Classes

This helps to improve code maintainability and control over the class hierarchy by enforcing compile-time inheritance restrictions that only a predetermined set of subclasses can inherit from the sealed class. By restricting which classes are permitted to extend a superclass or implement an interface, sealed classes in Java help developers in misuse and unintended sub-classing. In traditional Java, any non-final class can be extended by any other class.

Syntax of Sealed Classes

The sealed keyword and an allows clause, which enumerates the permitted subclasses, are the syntax for establishing a sealed class. Let’s examine a straightforward example:

// Sealed class with permitted subclasses
public sealed class Shape permits Circle, Rectangle, Triangle {
abstract double area();
}

// Final subclass: no further inheritance allowed
public final class Circle extends Shape {
private double radius;

public Circle(double radius) {
this.radius = radius;
}

@Override
public double area() {
return Math.PI * radius * radius;
}
}

// Sealed subclass: further restrictions can be applied
public sealed class Rectangle extends Shape permits Square {
private double width, height;

public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}

@Override
public double area() {
return width * height;
}
}

// Final subclass extending a sealed class
public final class Square extends Rectangle {
public Square(double side) {
super(side, side);
}
}

// Non-sealed subclass: unrestricted inheritance allowed
public non-sealed class Triangle extends Shape {
private double base, height;

public Triangle(double base, double height) {
this.base = base;
this.height = height;
}

@Override
public double area() {
return 0.5 * base * height;
}
}

Explanation

  • Final Class: “Shape” is classified as a sealed class, which means that it can only be extended by the subclasses specified in the permitted clause. The (Circle), (Rectangle), and (Triangle) subclasses are allowed in this example.
  • Sealed Subclass: The subclass “circle” is considered as Final, which means it cannot be further extended by any other class.
  • Final Subclass: The subclass “square” is considered as final so no further inheritance is allowed.
  • Sealed Subclass: subclass rectangle is itself declared as sealed, and it permits only one subclass “square”.
  • Non-Sealed Class: subclass Triangle is considered as Non-Sealed, which means it can be extended by any other class without any restriction.

Why Use Sealed Classes in Java?

Compared to conventional inheritance models, sealed classes in Java provide a number of benefits. Let’s talk about a few of the main advantages:

1. Improve Code Maintainability

Java developers can better manage the class hierarchy by clearly defining which classes are allowed to extend a sealed class. This lessens the possibility of inadvertent subclassing, which facilitates code evolution and maintenance.

2. Enhance Readability

It is instantly apparent which subclasses are permitted to extend sealed classes in Java when it is utilized. This makes the code easier to comprehend and gives Java developers a quick overview of the inheritance structure.

3. Better Design Control

A compromise between open inheritance and final classes is offered by sealed classes. Developers may fine-tune inheritance by defining precisely which classes are permitted to extend sealed classes in Java. Whereas, non-final classes can be extended by any class and final classes cannot be extended at all.

4. Better Exhaustiveness Checking

Pattern matching works well with sealed classes in Java, enabling the compiler to carry out thorough inspections. This lowers the possibility of runtime problems by allowing the compiler to guarantee that all potential scenarios are handled when utilizing sealed classes in Java pattern matching for switch expression. The compiler is aware that the only legitimate subclasses of Shape are Circle, Rectangle, and Triangle because Shape is a sealed class. This guarantees that every scenario is covered by the switch statement.

Example of Exhaustiveness Checking:

public double calculateArea(Shape shape) {
return switch (shape) {
case Circle c -> c.area();
case Rectangle r -> r.area();
case Triangle t -> t.area();
};
}

Use Cases of Sealed Classes

When a predetermined set of subclasses is needed, sealed classes are very helpful. Typical use scenarios include the following:

1) Algebraic Data Types (ADTs)

Sealed classes can be used to describe algebraic data types, which are common in functional programming languages. For example, you may express different states, forms, or responses with sealed classes.

2) Defining API Contracts

You might wish to limit which classes can extend specific abstract classes or implement particular interfaces while creating an API. By enforcing such limitations, sealed classes guarantee that only reliable implementations are utilized.

3) Enhancing Security

Sealed classes in Java can improve system security by limiting inheritance and preventing the creation of harmful or unauthorized subclasses.

Limitations of Sealed Classes

Limitations of Sealed Classes in Java

Although sealed courses have several advantages, they also have certain drawbacks.

=>Enhanced Intricacy

Design and maintenance complexity is increased with sealed classes. Developers must closely monitor the list of allowed subclasses, particularly as the system develops.

=>Needs Java 17 or Higher

Since sealed classes were completed in Java 17, they aren’t accessible in previous Java versions. This may restrict the use of sealed classes in Java on projects that continue to use outdated language versions.

=>Limited Flexibility

After a sealed class is defined, it must be modified in order to add new subclasses. In situations where it is necessary to introduce new kinds on a regular basis, this may be restricting.

Best Practices for Using Sealed Classes

When dealing with sealed classes, bear the following best practices in mind:

  • For Closed Hierarchies: In situations when the collection of subclasses is known and unlikely to change often, sealed classes work well.
  • Make Use of Pattern Matching: To write more legible and succinct code, use pattern matching with sealed classes.
  • Maintain a Simple Hierarchy: Steer clear of building hierarchies with a lot of layers of sealed subclasses. This may make it more difficult to read and update the code.
  • Subclasses of Documents Permitted: Each approved subclass’s purpose and the justification for extending the sealed class should be clearly documented.

Conclusion

Sealed classes in Java offer a strong tool for managing inheritance and guaranteeing improved object-oriented system architecture. Java developers may write more secure, understandable, and manageable code by clearly defining which classes are allowed to extend a sealed class. Although they might not be appropriate in every application, sealed classes are particularly advantageous when a closed set of subclasses is needed.

Sealed classes, along with capabilities like pattern matching, will become more and more crucial to contemporary Java web development as the language develops. Consider utilizing sealed classes in Java enhance the overall organization and maintainability of the code. When used appropriately, sealed classes may assist in creating strong and clear class hierarchies, which will eventually make your Java code simpler to read and maintain.

Read more:

Harsh Savani

Harsh Savani is an accomplished Business Analyst with a strong track record of bridging the gap between business needs and technical solutions. With 15+ of experience, Harsh excels in gathering and analyzing requirements, creating detailed documentation, and collaborating with cross-functional teams to deliver impactful projects. Skilled in data analysis, process optimization, and stakeholder management, Harsh is committed to driving operational efficiency and aligning business objectives with strategic solutions.

Scroll to Top