本文目录导读:

Java密封类(Sealed Class)是Java 17正式引入的一个特性,它提供了一种比final更灵活的继承控制方式,下面是实际开发中的典型使用场景和具体代码示例。
核心用途:精确控制继承体系
密封类允许你声明一个类或接口,明确指定哪些其他类或接口可以继承或实现它,这对以下场景特别有价值:
- 领域建模:如状态机、支付方式、用户角色等有限子集
- 模式匹配:配合
switch表达式实现穷举匹配 - API设计:防止用户意外扩展你的核心类层次结构
基本语法结构
// 定义密封接口
public sealed interface Vehicle permits Car, Truck, Motorcycle {
int getMaxSpeed();
}
// 必须声明为 final、sealed 或 non-sealed
public final class Car implements Vehicle {
@Override
public int getMaxSpeed() {
return 200;
}
}
public final class Truck implements Vehicle {
@Override
public int getMaxSpeed() {
return 120;
}
}
// 允许继续扩展
public non-sealed class Motorcycle implements Vehicle {
@Override
public int getMaxSpeed() {
return 250;
}
}
实际项目场景示例
场景1:状态机(订单状态)
// 定义密封的订单状态
public sealed interface OrderState
permits Pending, Confirmed, Shipped, Delivered, Cancelled {
boolean canTransitionTo(OrderState target);
String getDisplayName();
}
// 各个具体状态
public final class Pending implements OrderState {
@Override
public boolean canTransitionTo(OrderState target) {
return target instanceof Confirmed || target instanceof Cancelled;
}
@Override
public String getDisplayName() {
return "待确认";
}
}
public final class Confirmed implements OrderState {
@Override
public boolean canTransitionTo(OrderState target) {
return target instanceof Shipped || target instanceof Cancelled;
}
@Override
public String getDisplayName() {
return "已确认";
}
}
// ... 其他状态类类似
// 使用密封类配合 switch 穷举
public boolean processOrderState(OrderState current, OrderState target) {
// 编译器可以保证覆盖所有状态
String message = switch (current) {
case Pending p -> {
System.out.println("处理待确认订单");
yield p.canTransitionTo(target) ? "可以转换" : "不能转换";
}
case Confirmed c -> {
System.out.println("处理已确认订单");
yield c.canTransitionTo(target) ? "可以转换" : "不能转换";
}
case Shipped s -> {
System.out.println("处理运输中订单");
yield s.canTransitionTo(target) ? "可以转换" : "不能转换";
}
case Delivered d -> "订单已完成,不能转换";
case Cancelled c -> "订单已取消,不能转换";
};
return "可以转换".equals(message);
}
场景2:支付方式处理
// 密封的支付方式接口
public sealed interface PaymentMethod
permits CreditCard, DebitCard, Alipay, WeChatPay {
boolean processPayment(double amount);
String getPaymentType();
}
// 信用卡支付
public final class CreditCard implements PaymentMethod {
private final String cardNumber;
private final String cvv;
public CreditCard(String cardNumber, String cvv) {
this.cardNumber = cardNumber;
this.cvv = cvv;
}
@Override
public boolean processPayment(double amount) {
System.out.println("信用卡支付:" + amount);
return true;
}
@Override
public String getPaymentType() {
return "信用卡";
}
}
// 支付宝支付
public final class Alipay implements PaymentMethod {
private final String userId;
public Alipay(String userId) {
this.userId = userId;
}
@Override
public boolean processPayment(double amount) {
System.out.println("支付宝支付:" + amount);
return true;
}
@Override
public String getPaymentType() {
return "支付宝";
}
}
// ... 其他支付方式类似
// 支付处理器,利用密封类保证穷举
public class PaymentProcessor {
public String getPaymentDescription(PaymentMethod payment) {
// 编译器会检查是否覆盖了所有支付方式
return switch (payment) {
case CreditCard c -> "信用卡支付 - " + c.getPaymentType();
case DebitCard d -> "借记卡支付 - " + d.getPaymentType();
case Alipay a -> "支付宝支付 - " + a.getPaymentType();
case WeChatPay w -> "微信支付 - " + w.getPaymentType();
};
}
public boolean pay(PaymentMethod method, double amount) {
System.out.println("使用" + method.getPaymentType() + "支付");
return method.processPayment(amount);
}
}
场景3:表达式解析器(AST节点)
// 密封的表达式节点
public sealed interface Expression
permits NumberExpr, BinaryExpr, UnaryExpr, VariableExpr {
int evaluate(Context context);
}
// 数字表达式
public final class NumberExpr implements Expression {
private final int value;
public NumberExpr(int value) {
this.value = value;
}
@Override
public int evaluate(Context context) {
return value;
}
}
// 二元操作表达式
public final class BinaryExpr implements Expression {
private final Expression left;
private final Expression right;
private final String operator;
public BinaryExpr(Expression left, Expression right, String operator) {
this.left = left;
this.right = right;
this.operator = operator;
}
@Override
public int evaluate(Context context) {
return switch (operator) {
case "+" -> left.evaluate(context) + right.evaluate(context);
case "-" -> left.evaluate(context) - right.evaluate(context);
case "*" -> left.evaluate(context) * right.evaluate(context);
case "/" -> left.evaluate(context) / right.evaluate(context);
default -> throw new IllegalArgumentException("未知操作符");
};
}
}
// ... 其他表达式类型
// 表达式计算器
public class ExpressionEvaluator {
public String describeExpression(Expression expr) {
// 穷举匹配,编译器保证
return switch (expr) {
case NumberExpr n -> "常量: " + n.evaluate(null);
case BinaryExpr b -> "二元操作";
case UnaryExpr u -> "一元操作";
case VariableExpr v -> "变量引用";
};
}
}
关键注意事项
继承要求
- 所有允许的子类必须与密封类在同一个模块中(Java 17)
- 如果不在同一包,必须放在同一模块内
- 每个子类必须显式声明为
final、sealed或non-sealed
模块系统配合
// 在 module-info.java 中导出密封类
module com.example.payments {
exports com.example.payments.model; // 包含密封类 PaymentMethod
exports com.example.payments.impl; // 包含实现类
}
与记录类(Record)结合
// 记录类天然是 final 的,非常适合作为密封类的子类
public sealed interface Shape permits Circle, Rectangle, Triangle { }
public record Circle(double radius) implements Shape { }
public record Rectangle(double width, double height) implements Shape { }
public record Triangle(double base, double height) implements Shape { }
什么时候使用密封类?
- 你的领域模型有明确的有限子类型集合
- 需要编译器保证 switch 表达式的穷举性
- 设计框架或API时,希望控制用户扩展的范围
- 状态机、表达式树、命令模式等场景
什么时候不要用?
- 子类型可能由第三方扩展(如插件系统)
- 子类型数量可能动态增长
- 与现有的非密封类层次结构集成
密封类让继承关系变得可预测和可控,是Java迈向更安全、更可维护代码的重要一步。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播