如何通过Sealed Classes构建领域驱动设计中的受限代数数据类型?

2026-04-29 09:141阅读0评论SEO基础
  • 内容介绍
  • 相关推荐

本文共计848个文字,预计阅读时间需要4分钟。

如何通过Sealed Classes构建领域驱动设计中的受限代数数据类型?

Java 的密封类(`sealed`)配合 `record`,为数据类型(ADT)的量身定制提供了原生支持。它不依赖于接口模拟或抽象类,也不依赖手写的子类模板,而是通过编译器强制保证:

典型场景比如支付方式、订单状态、解析结果这类“有限且封闭”的业务概念——它们天然不是开放扩展的,而是有明确、固定种类的。这时候用 sealed interface 定义契约,用 record 实现具体变体,语义清晰、不可变、无冗余代码。

必须满足的三个语法硬约束

漏掉任意一条,编译直接报错,不是运行时问题:

  • sealed 接口或类必须显式带 permits 子句(除非所有子类与它在同一源文件中,此时可省略)
  • 每个被 permits 列出的实现类/子类,必须声明为 finalsealednon-sealed
  • record 实现密封接口时,必须加 final(哪怕不写,record 默认就是 final,但显式写上更安全、可读性更强)

switch 表达式能做穷尽检查的关键条件

只有当所有分支都覆盖了 permits 列出的类型,且这些类型本身是 final(或至少没有额外子类),编译器才允许你省略 default 分支。否则会报错:the switch expression does not cover all possible values

阅读全文

本文共计848个文字,预计阅读时间需要4分钟。

如何通过Sealed Classes构建领域驱动设计中的受限代数数据类型?

Java 的密封类(`sealed`)配合 `record`,为数据类型(ADT)的量身定制提供了原生支持。它不依赖于接口模拟或抽象类,也不依赖手写的子类模板,而是通过编译器强制保证:

典型场景比如支付方式、订单状态、解析结果这类“有限且封闭”的业务概念——它们天然不是开放扩展的,而是有明确、固定种类的。这时候用 sealed interface 定义契约,用 record 实现具体变体,语义清晰、不可变、无冗余代码。

必须满足的三个语法硬约束

漏掉任意一条,编译直接报错,不是运行时问题:

  • sealed 接口或类必须显式带 permits 子句(除非所有子类与它在同一源文件中,此时可省略)
  • 每个被 permits 列出的实现类/子类,必须声明为 finalsealednon-sealed
  • record 实现密封接口时,必须加 final(哪怕不写,record 默认就是 final,但显式写上更安全、可读性更强)

switch 表达式能做穷尽检查的关键条件

只有当所有分支都覆盖了 permits 列出的类型,且这些类型本身是 final(或至少没有额外子类),编译器才允许你省略 default 分支。否则会报错:the switch expression does not cover all possible values

阅读全文