Java 15密封类(Sealed Classes):提升代码的安全性和可维护性

2025-04发布7次浏览

Java 15 密封类(Sealed Classes):提升代码的安全性和可维护性

引言

Java 15引入了密封类(Sealed Classes),这是一个新的特性,旨在增强代码的安全性和可维护性。通过限制某个类或接口的子类型数量,开发者可以更好地控制继承结构,从而减少潜在的错误和不必要的复杂性。

什么是密封类?

密封类允许一个类或接口声明其仅能被特定的其他类或接口所扩展或实现。这意味着,只有那些明确被允许的类可以继承或实现密封类,其他任何类都不能这样做。这有助于构建更安全、更易于理解的继承层次结构。

密封类的关键字
  • sealed:用于标记一个类或接口为密封。
  • permits:指定哪些类可以扩展或实现该密封类。
  • non-sealed:用于在密封类中嵌套定义非密封类。

使用场景

密封类特别适用于需要对类的继承进行严格控制的场景,例如:

  • 定义一组有限的子类来表示某种状态或行为。
  • 防止外部不可信的类随意扩展核心逻辑。

实践步骤与代码示例

以下是一个简单的例子,展示如何使用密封类来定义一个有限的继承结构。

步骤1:定义一个密封类
public sealed class Shape permits Circle, Rectangle, Triangle {
    // 这个类只能被Circle、Rectangle和Triangle继承
}
步骤2:定义允许的子类
public final class Circle extends Shape {
    private double radius;

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

    public double getRadius() {
        return radius;
    }
}

public final class Rectangle extends Shape {
    private double width;
    private double height;

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

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }
}

public final class Triangle extends Shape {
    private double base;
    private double height;

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

    public double getBase() {
        return base;
    }

    public double getHeight() {
        return height;
    }
}
步骤3:尝试创建非法的子类

如果尝试创建一个不在permits列表中的子类,编译器会报错。例如:

// 编译错误:The type Square is not allowed to extend or implement the sealed type Shape
public class Square extends Shape {
    private double side;

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

    public double getSide() {
        return side;
    }
}
步骤4:使用密封类
public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle(5.0);
        Shape rectangle = new Rectangle(4.0, 6.0);
        Shape triangle = new Triangle(3.0, 7.0);

        System.out.println("Circle radius: " + ((Circle)circle).getRadius());
        System.out.println("Rectangle dimensions: " + ((Rectangle)rectangle).getWidth() + "x" + ((Rectangle)rectangle).getHeight());
        System.out.println("Triangle base and height: " + ((Triangle)triangle).getBase() + ", " + ((Triangle)triangle).getHeight());
    }
}

扩展知识

  • 模式匹配:Java 16引入了与密封类结合使用的模式匹配功能,进一步增强了类型检查的能力。
  • 非密封类:即使在一个密封类中,也可以通过non-sealed关键字定义一个非密封的子类,允许其继续被扩展。
  • 安全性:通过限制类的继承,密封类可以帮助防止恶意代码滥用继承机制。