Java 15密封类sealed关键字详解
请详细解释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:有控制地允许特定类继承
解决的问题:
- 域建模:明确有限的子类型集合(如JSON节点、表达式树)
- 穷尽性检查:switch表达式可检查是否覆盖了所有子类型(搭配模式匹配)
- 安全性:防止API被意外扩展
- 代数数据类型(ADT):Java向函数式语言靠拢
限制:
- sealed类和子类必须在同一个模块(模块化)或同一个包(非模块化)中
- 子类必须直接继承,不能间接