tww*_*wwt 6 java sealed sealed-class java-17
如果我正确地阅读了 JLS \xc2\xa78.1.6和\xc2\xa79.1.4,则密封类/接口允许的类只是直接子类/接口。
\n为了说明这一点,请考虑以下示例:
\npublic sealed interface I1 permits I2, C, D { /*...*/ }\npublic final class C implements I1 { /*...*/ }\npublic final class D implements I1 { /*...*/ }\n\npublic sealed interface I2 extends I1 permits E, F { /*...*/ }\npublic final class E implements I2 { /*...*/ }\npublic final class F implements I2 { /*...*/ }\nRun Code Online (Sandbox Code Playgroud)\n如果我正确理解了规范,I1显然允许CandD但不允许Eand F(通过fromextends的层次结构)。它是否正确?I2I1
我问的原因是以下类型的 switch 表达式允许使用哪些模式:
\nI1 i1 = // ...\nreturn switch (i1) {\n case C c -> "1";\n case D d -> "2";\n case E e -> "3"; // Can we match over E?\n case F f -> "4"; // Can we match over F?\n default -> "5";\n};\nRun Code Online (Sandbox Code Playgroud)\n
I1显然允许C且 ,D但不允许E和F。它是否正确?
更准确地说,您可以说C和位于 的允许的直接子类集合D中,这是第 9.1.4 节中定义的术语。JLS 并没有真正定义“允许和”的含义。I1I1 CD
至于你的 switch 表达式,它起作用的原因有两个。首先,如果开关选择器表达式的类型可向下转换为该类型,则可以在开关标签中编写类型模式。
如果 p 适用于类型 T(14.30.3),则模式 case 元素 p 与 T 兼容。
14.30.3:
如果以下规则之一适用,则称模式 p 适用于类型 T:
- 如果 T 可以向下转换为 U ( 5.5 ) ,则声明引用类型 U 的模式变量的类型模式适用于另一个引用类型 T。
显然,可以通过扩大引用转换E进行向下转换,因为实现了. 请注意,这个事实与 无关。它只是和的结果。你肯定会同意这一点并且是传递性的!I1EI1permitsE implements I2I2 extends I1implementsextends
其次,switch 表达式需要详尽无遗。你的 switch 表达式总是详尽的,因为它有一个default案例。然而,即使没有案例,它仍然是详尽的default。
从现在开始,我们将考虑您的 switch 表达式,但不考虑大小写default,因为这才是permits发挥作用的地方。确定您编写的案例标签集是否详尽的规则在14.11.1.1中指定。您的案例的重要部分是(这是一种归纳定义):
- 如果一组 case 元素包含在类型 T 上无条件的模式,那么它对于类型 T 来说是详尽的(14.30.3)。
- 如果一组 case 元素对于 T 的每个适用的允许的直接子类型都是穷举的,则对于包含名为 C 的抽象密封类或接口的类型 T 来说,它是穷举的。
在您的情况下,“适用的允许的 T 的直接子类型”实际上与“允许的 T 的直接子类型”相同。您还可以将“包含抽象且密封的类或名为 C 的接口的类型 T”视为相同T- “包含”关系与您的情况无关。记住T=I1了,我们就可以开始“运行”这个算法了。
我们首先使用第二条规则 - 允许的直接子类型I1是I2,C和D。因为我们在 case 元素中有一个C cand ,所以我们知道我们的 case 元素集对于and (第一条规则)是详尽的。它也详尽无遗吗?为了确定这一点,我们再次使用第二条规则。允许的直接子类型是和。使用第一条规则,我们知道 case 元素和分别对于和是详尽的。我们现在已经证明,根据第二条规则,案例元素集对于 和 是详尽的,因此对于 也是详尽的。D dCDI2I2EFE eF fEFI2CDI1
因此,如果您正在谈论开关模式的工作原理,我认为“归纳”是一个更好的词来描述如何验证开关盒标签的详尽性。
| 归档时间: |
|
| 查看次数: |
1166 次 |
| 最近记录: |