代码对比
✕ Java 8
// Must add default even though
// all cases are covered
double area(Shape s) {
if (s instanceof Circle c)
return Math.PI * c.r() * c.r();
else if (s instanceof Rect r)
return r.w() * r.h();
else throw new IAE();
}
✓ Java 21+
// sealed Shape permits Circle, Rect
double area(Shape s) {
return switch (s) {
case Circle c ->
Math.PI * c.r() * c.r();
case Rect r ->
r.w() * r.h();
}; // no default needed!
}
发现此代码有问题? 告诉我们。
为什么现代方式更好
编译时安全
添加新子类型时,编译器会显示每个需要更新的地方。
无死代码
没有掩盖 bug 的不可达 default 分支。
代数类型
密封类 + record + 穷举 switch = Java 中的正式 ADT。
旧方式
强制 default 分支
现代方式
密封类穷举性
自 JDK
21
难度
中级
JDK 支持
无 default 的穷举 switch
可用
自 JDK 21 LTS 起广泛可用(2023 年 9 月)
工作原理
对密封类型进行 switch 时,编译器在编译时知道所有可能的子类型。如果所有情况均已覆盖,则不需要 default 分支。
相关文档