Embracing Modernity: A Comprehensive Look at Sealed Classes, Pattern Matching, and Functional Paradigms in Java


The introduction of Sealed Classes in Java and the combination with pattern matching in switch statements has sparked a debate among software developers. 

The argument in question raises concerns about the real-life use cases for Sealed Classes and suggests that pattern matching with switch might promote poor coding practices. 

This article aims to counter these assertions by examining the principles and practical applications of Sealed Classes and pattern matching.

Understanding Sealed Classes

Definition and Purpose

Sealed Classes are a feature introduced in Java to allow a class to permit specific subclasses and prevent any other class from extending it. They provide a way to represent restricted hierarchies where a superclass knows all its subclasses.

Real-life Use-Cases

Contrary to the belief that Sealed Classes will have few real-life applications, they provide several key benefits:

Enhanced Maintainability: By constraining subclassing, developers can easily understand the codebase, making it easier to maintain.

Robust Security: Sealed Classes prevent unauthorized classes from extending critical parts of a system.

Improved Performance: Compiler optimizations are possible as the compiler knows the entire hierarchy, potentially improving runtime performance.

Pattern Matching and Switch Statements

Definition and Application

Pattern matching in switch statements simplifies the coding of multi-case conditional statements. It provides a cleaner and more readable code structure.

Proper Design in OO Systems

The claim that pattern matching with switch promotes dubious coding practices in Object-Oriented (OO) systems needs examination:

Enhanced Readability: Pattern matching in switch enhances code readability by reducing boilerplate code, promoting more maintainable OO designs.

Flexibility: It offers a flexible way to deal with various object structures without violating OO principles.

Type Safety: This approach promotes type safety and ensures that developers adhere to proper coding practices.

Code Examples

Sealed Classes

public sealed interface Shape permits Circle, Rectangle, Square {

final class Circle implements Shape {
private final double radius;

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

final class Rectangle implements Shape {
private final double width;
private final double height;

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

non-sealed class Square implements Shape {
private final double side;

public Square(double side) {
this.side = side;

Pattern Matching and Switch Statements

public static String getShapeDescription(Shape shape){
return switch (shape) {
case Circle circle -> “Circle with radius ” + circle.getRadius();
case Rectangle rectangle -> “Rectangle with width ” + rectangle.getWidth() + ” and height ” + rectangle.getHeight();
case Square square -> “Square with side ” + square.side;

Functional Paradigm and Its Relevance

The functional paradigm emphasizes immutability, first-class functions, and declarative programming. Java has increasingly adopted features that align with functional programming, enhancing OO principles in various ways.

Sealed Classes in a Functional Context

Immutable Hierarchies: Sealed Classes often lead to hierarchies where instances are immutable.

Pattern Exhaustiveness: By defining a fixed set of permitted subclasses, Sealed Classes ensure that all possible cases are handled.

Pattern Matching, Switch Statements, and Functional Programming

Declarative Syntax: The concise and expressive syntax of pattern matching aligns with the declarative nature of functional programming.

Functional Flow Control: Pattern matching provides a more functional way to handle control flow.

Code Example: Functional Approach

public sealed interface Shape permits Circle, Rectangle, Square { }
record Circle(double radius) implements Shape { }
record Rectangle(double length, double width) implements Shape { }
record Square(double side) implements Shape { }

//We can still have the same getShapeDescription() method

public static String getShapeDescription(Shape shape) {

return switch (shape) {
case Circle c -> “This is a circle with radius: ” + c.radius();
case Rectangle r -> “This is a rectangle with length: ” + r.length() + ” and width: ” + r.width();
case Square s -> “This is a square with side length: ” + s.side();



Sealed Classes and pattern matching with switch statements are not merely syntactic sugar but tools that provide real value to Java programmers. 

They serve specific purposes that enhance code maintainability, security, performance, and readability. 

Far from promoting dubious coding practices, these features help developers create more robust and elegant solutions.

Java continues to evolve, embracing the strengths of different paradigms, and developers must recognize the value these additions bring. 

Sealed Classes, pattern matching, and the integration of functional programming are not isolated enhancements but a cohesive effort to make Java a language capable of meeting the complex and diverse needs of modern software engineering. 

The real-life use cases for these features are not rare but abundant, and their integration into Java’s ecosystem signals a promising direction for the language and its community.

The post Embracing Modernity: A Comprehensive Look at Sealed Classes, Pattern Matching, and Functional Paradigms in Java appeared first on foojay.