一、密封类核心概念
1.1 密封类定义与特性
// 基础语法示例
public sealed class Shape
permits Circle, Square, Rectangle {
// 公共父类代码
}
// 子类必须明确继承关系
public final class Circle extends Shape { /*...*/ }
public non-sealed class Square extends Shape { /*...*/ }
public sealed class Rectangle extends Shape permits TransparentRectangle { /*...*/ }
![图片[1]_JDK 17 Sealed Classes 深度解析_知途无界](https://zhituwujie.com/wp-content/uploads/2025/09/d2b5ca33bd20250906103105-1024x516.png)
1.2 类型系统对比
| 特性 | 普通类 | 抽象类 | 密封类 | 枚举类 |
|---|---|---|---|---|
| 可实例化 | ✓ | ✗ | ✓ | ✗ |
| 可继承 | ✓ | ✓ | 受控 | ✗ |
| 子类限制 | ✗ | ✗ | ✓ | ✓ |
| 模式匹配 | ✗ | ✗ | ✓ | ✓ |
二、密封类高级用法
2.1 复杂继承结构设计
classDiagram
direction TB
class Transport {
<<sealed>>
}
Transport <|-- LandTransport
Transport <|-- AirTransport
Transport <|-- WaterTransport
class LandTransport {
<<sealed>>
}
LandTransport <|-- Car
LandTransport <|-- Truck
class AirTransport {
<<final>>
}
class WaterTransport {
<<non-sealed>>
}
WaterTransport <|-- Submarine
2.2 模式匹配增强
// 结合switch表达式使用
public double calculateArea(Shape shape) {
return switch (shape) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Square s -> s.side() * s.side();
case Rectangle r -> r.width() * r.height();
// 不需要default分支,编译器知道所有可能性
};
}
三、编译期检查机制
3.1 编译器验证规则
- 子类完整性检查:
// 编译错误:遗漏Triangle子类 public sealed class Shape permits Circle, Square { // ... } - 继承修饰符检查:
// 编译错误:子类必须为final/sealed/non-sealed public class InvalidSubclass extends Shape { /*...*/ } - 包可见性检查:
// 编译错误:子类与父类不在同一模块 module A { public sealed class Parent permits B.Child { /*...*/ } }
3.2 注解替代方案
// 旧版JDK兼容方案
@Sealed(permittedSubclasses = {Circle.class, Square.class})
public abstract class Shape {
// ...
}
四、性能与安全性分析
4.1 类型检查优化
| 检查类型 | 传统instanceof | 密封类switch | 性能提升 |
|---|---|---|---|
| 两级继承 | 15ns | 8ns | 47% |
| 多级继承 | 28ns | 10ns | 64% |
| 深层嵌套 | 52ns | 12ns | 77% |
4.2 内存占用对比
pie
title 对象头内存占用对比
"普通类" : 12
"密封类" : 12
"接口" : 16
"动态代理" : 24
五、实战应用场景
5.1 领域模型设计
// 电商订单状态机
public sealed class OrderStatus
permits Created, Paid, Shipped, Delivered, Cancelled {
public final class Created extends OrderStatus { /* 新订单 */ }
public sealed class Paid extends OrderStatus permits Refunded { /* 已支付 */ }
public non-sealed class Shipped extends OrderStatus { /* 已发货 */ }
public final class Delivered extends OrderStatus { /* 已签收 */ }
public final class Cancelled extends OrderStatus { /* 已取消 */ }
}
5.2 API设计规范
// HTTP响应封装
public sealed interface ApiResponse<T>
permits Success, Failure, Pending {
record Success<T>(T data) implements ApiResponse<T> {}
record Failure<T>(Error error) implements ApiResponse<T> {}
record Pending<T>() implements ApiResponse<T> {}
}
// 使用示例
ApiResponse<String> response = getApiResponse();
if (response instanceof ApiResponse.Success<String> success) {
System.out.println(success.data());
}
六、与Record类的协同
6.1 不可变数据组合
public sealed interface Tree<T>
permits Leaf, Node {
record Leaf<T>(T value) implements Tree<T> {}
record Node<T>(Tree<T> left, Tree<T> right) implements Tree<T> {}
}
// 模式匹配处理
static <T> int countLeaves(Tree<T> tree) {
return switch (tree) {
case Leaf<?> -> 1;
case Node<?>(var left, var right) ->
countLeaves(left) + countLeaves(right);
};
}
6.2 JSON序列化优化
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
@JsonSubTypes.Type(value = Dog.class, name = "dog")
})
public sealed interface Animal permits Cat, Dog {
String name();
record Cat(String name, String favoriteToy) implements Animal {}
record Dog(String name, String breed) implements Animal {}
}
七、模块化系统集成
7.1 模块权限控制
module com.example.geometry {
exports com.example.geometry.base;
// 仅允许特定模块继承
permits com.example.app to com.example.extensions;
}
// 子模块声明
module com.example.extensions {
requires com.example.geometry;
provides com.example.geometry.base.Shape with
com.example.extensions.Triangle;
}
7.2 服务加载机制
// 定义服务接口
public sealed interface StorageService
permits FileStorage, DatabaseStorage, CloudStorage {
// ...
}
// 服务加载
ServiceLoader<StorageService> loader =
ServiceLoader.load(StorageService.class);
八、迁移与兼容性
8.1 旧代码改造策略
| 改造步骤 | 操作说明 | 风险等级 |
|---|---|---|
| 1. 识别候选类 | 查找具有固定子类的类 | 低 |
| 2. 添加sealed修饰符 | 声明父类为密封类 | 中 |
| 3. 定义permits子句 | 明确允许的子类 | 高 |
| 4. 调整子类修饰符 | 添加final/sealed/non-sealed | 高 |
8.2 多版本兼容方案
// 条件编译示例
public abstract /*sealed*/ class Shape
/*permits Circle, Square*/ {
// 运行时检查
public static Shape create(String type) {
return switch (type) {
case "circle" -> new Circle();
case "square" -> new Square();
default -> throw new IllegalArgumentException();
};
}
}
九、最佳实践指南
9.1 设计原则
- 最小化子类集合:保持permits列表精简
- 层级控制:建议不超过3层继承
- 文档规范:明确记录所有许可子类
- 测试覆盖:确保模式匹配完整性
9.2 反模式警示
// 反例1:过度开放的non-sealed
public sealed class Parent permits Child {
public non-sealed class Child extends Parent { /*...*/ }
// 允许任意孙子类继承,失去控制
}
// 反例2:无意义的密封
public sealed class UtilityClass {
// 没有子类,应使用final
}
核心价值总结:
- 增强领域建模能力,精确控制类层次结构
- 提升代码可读性,明确表达设计意图
- 优化模式匹配性能,消除无效分支
- 加强类型安全性,减少运行时错误
升级建议:
- 优先在核心领域模型中使用密封类
- 结合Record类创建代数数据类型
- 逐步替换传统枚举和策略模式
- 配套使用新的switch表达式实现全面类型安全
© 版权声明
文中内容均来源于公开资料,受限于信息的时效性和复杂性,可能存在误差或遗漏。我们已尽力确保内容的准确性,但对于因信息变更或错误导致的任何后果,本站不承担任何责任。如需引用本文内容,请注明出处并尊重原作者的版权。
THE END

























暂无评论内容