【JDK 17】密封类 sealed、permits、non-sealed

密封类(Sealed Classes)

一、作用

限制类的继承实现, 只允许指定的子类去继承

二、关键字

sealed 、permits、non-sealed

三、使用

使用时,密封类的父子类 必须 是同包

写法 一

父类定义
sealed 声明密封类

sealed class 父类名 permits 子类名A, 子类名B, 子类名C { //逻辑代码 } 

子类定义
final 修饰被无法继承

final class 子类名A extends 父类名 { //逻辑代码 }

non-sealed 修饰可被子类继承

non-sealed class 子类名B extends 父类名 { //逻辑代码 }

sealed 子类也可以是密封类

sealed class 子类名C extends 父类名 { //逻辑代码 }
final class 子类名A extends 父类名 { //逻辑代码 }

non-sealed 修饰可被子类继承

non-sealed class 子类名B extends 父类名 { //逻辑代码 }

sealed 子类也可以是密封类

sealed class 子类名C extends 父类名 { //逻辑代码 }

写法 二

sealed class 父类名{ 
    public final class 子类名A extends 父类名 { //逻辑代码 }
    public non-sealed class 子类名B extends 父类名 { //逻辑代码 }
    public sealed class 子类名C extends 父类名 { //逻辑代码 }
} 

<think>嗯,用户想知道JDK17密封类的使用场景和示例。首先,我需要回顾一下密封类的基本概念。根据引用[2],密封类允许开发者控制哪些类可以继承或实现某个类或接口,这样可以提供更严格的继承控制,增强代码的安全性和可维护性。 接下来,我得考虑用户可能需要的具体例子。比如,在什么情况下会用到密封类呢?常见的应用场景可能有领域模型设计、状态机、表达式树等。比如在金融系统中,不同的账户类型可能需要不同的处理,这时候密封类可以限制子类,避免其他人添加未授权的类型。 然后,我需要确保示例代码符合Java 17的语法。密封类使用sealed关键字,并且用permits子句指定允许的子类。子类必须是final、sealed或non-sealed。例如,定义一个密封类Shape,允许Circle和Rectangle作为子类,这样其他类就不能继承Shape,除非明确允许。 另外,用户可能想知道密封类如何与模式匹配结合使用,比如在switch语句中,根据不同的子类执行不同的操作。引用[3]提到JDK17支持在switch中使用模式匹配,所以可以举一个使用instanceof检查类型并处理的例子。 还要注意密封类在接口上的应用,比如定义权限系统,允许特定的实现类。这样在编译时就能检查所有可能的子类,避免遗漏case,提高代码的健壮性。 最后,需要总结密封类的优势,如限制继承范围、增强类型安全、便于模式匹配等,并指出适用场景,如需要严格控制继承关系的场景。同时,确保引用正确的文献来源,比如引用[2]和引用[3]。</think>### JDK17 密封类使用场景及示例 #### 1. 密封类核心作用 密封类通过`sealed`关键字和`permits`子句限定可继承的子类,提供**编译期强约束的类继承控制**,适用于需要严格限制继承关系的场景[^2]。 #### 2. 典型使用场景 **场景一:领域模型设计** ```java // 定义图形类型密封类 public sealed abstract class Shape permits Circle, Rectangle, Triangle { // 只允许三个子类 public abstract double area(); } // 具体子类必须声明为 final/sealed/non-sealed final class Circle extends Shape { private final double radius; public double area() { return Math.PI * radius * radius; } } final class Rectangle extends Shape { private final double width, height; public double area() { return width * height; } } non-sealed class Triangle extends Shape { // 允许Triangle被继续扩展 protected double base, height; public double area() { return 0.5 * base * height; } } ``` **优势**:防止出现未定义的图形类型,保证`switch`模式匹配的完整性检查[^3]。 --- **场景二:状态机实现** ```java // 定义工作流状态机 public sealed interface WorkflowState permits Draft, Submitted, Approved, Rejected {} final class Draft implements WorkflowState {} final class Submitted implements WorkflowState {} final class Approved implements WorkflowState {} final class Rejected implements WorkflowState {} ``` **优势**:确保状态流转的合法性,例如从`Draft`只能转换到`Submitted`,避免无效状态出现。 --- **场景三:表达式树处理** ```java // 定义算术表达式结构 public sealed interface Expr permits ConstantExpr, PlusExpr, MinusExpr, TimesExpr {} record ConstantExpr(int value) implements Expr {} record PlusExpr(Expr left, Expr right) implements Expr {} record MinusExpr(Expr left, Expr right) implements Expr {} record TimesExpr(Expr left, Expr right) implements Expr {} ``` **优势**:结合模式匹配特性实现安全计算: ```java static int evaluate(Expr e) { return switch(e) { case ConstantExpr c -> c.value(); case PlusExpr p -> evaluate(p.left()) + evaluate(p.right()); case MinusExpr m -> evaluate(m.left()) - evaluate(m.right()); case TimesExpr t -> evaluate(t.left()) * evaluate(t.right()); // 不需要default分支,编译器验证了所有可能性 }; } ``` --- #### 3. 接口密封控制 ```java // 定义权限系统接口 public sealed interface AuthProvider permits DatabaseAuth, LdapAuth, OAuth2 {} // 限定认证方式 final class DatabaseAuth implements AuthProvider { /* 数据库认证 */ } final class LdapAuth implements AuthProvider { /* LDAP认证 */ } final class OAuth2 implements AuthProvider { /* OAuth2认证 */ } ``` #### 4. 核心优势总结 | 特性 | 传统继承 | 密封类 | |--------------------|------------------------|--------------------------| | 继承控制 | 完全开放 | 白名单控制 | | 模式匹配安全性 | 需要default分支 | 编译器验证分支完整性 | | 代码可维护性 | 容易产生不可控子类 | 明确继承关系树 | **适用场景**:金融领域金额类型、编译器AST节点、协议消息格式等需要严格类型控制的场景[^2][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码鹿的笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值