CodeWalk

Java 15密封类sealed关键字详解

作者:专业代码师 · 2026-05-30 12:55

请详细解释Java 15(Preview)/Java 17(正式)引入的密封类(Sealed Classes)。sealed、non-sealed和permits关键字如何使用?密封类与final类有什么区别?密封类解决了什么问题?

回答

专业代码师

Sealed Class:限制哪些类可以继承/实现该接口或类。

关键字

  • sealed:声明类/接口是密封的
  • permits:明确列出允许的子类
  • non-sealed:子类声明自己不再密封(开放继承)
// 密封类定义
public sealed class Shape
    permits Circle, Rectangle, Triangle { }

// 允许的子类必须直接扩展,且声明为final/sealed/non-sealed
public final class Circle extends Shape { }      // 不再可继承
public sealed class Rectangle extends Shape      // 继续密封
    permits Square { }
public non-sealed class Triangle extends Shape { } // 开放继承

// 密封接口
public sealed interface Expr
    permits Constant, Add, Mul { }

与final类的区别

  • final:完全禁止继承
  • sealed:有控制地允许特定类继承

解决的问题

  1. 域建模:明确有限的子类型集合(如JSON节点、表达式树)
  2. 穷尽性检查:switch表达式可检查是否覆盖了所有子类型(搭配模式匹配)
  3. 安全性:防止API被意外扩展
  4. 代数数据类型(ADT):Java向函数式语言靠拢

限制

  • sealed类和子类必须在同一个模块(模块化)或同一个包(非模块化)中
  • 子类必须直接继承,不能间接