假设层次 struct 为sealed,如下所示

sealed interface Shape permits Rectangle, Square

record Rectangle() implements Shape

record Square() implements Shape

由于Rectangle&Square是记录,因此它固有地使整个层次 struct 不可扩展,即不再允许更多的子类.

从JDK 21开始,switch的模式匹配通过覆盖所有可能的case或提供default case 来覆盖其余部分,从而强制切换为穷举.

因此,对于低于switch的案件,在什么情况下会执行default起案件,因为所有可能的组合都包括在内,为什么甚至允许这样做?

switch (shape) {
    case Rectangle r -> // do something with r;
    case Square sq -> // do something with sq; 
    case null -> // shape could be null 
    default -> // WHY is this permitted when all possible cases are covered already??
    }

P.S.:密封的层次 struct 当然可以进化,但当这种情况发生时,编译器会自动标记switch来升级自己.

推荐答案

密封的层次 struct 当然可以进化,但是当这种情况发生时,编译器也会自动标记switch 以升级自身.

这不是真的.您似乎假设Switch语句和记录/密封接口将始终编译在一起.当然,在大多数实际情况下,这很可能是正确的,但并不是百分之百正确.您可以编译密封的接口和记录,而无需重新编译Switch语句.

例如,假设所有类型都位于单独的.Java文件中,并使用它们的名称命名,因此Shape.java、Recangle.java、Square.java,而Switch语句位于Main.java中的main方法中.

首先,我编译我拥有的所有Java源文件,并 for each .Java文件生成.class文件.

然后,假设我将Shape.java更改为:

sealed interface Shape permits Rectangle, Square, Triangle

并添加了一个Triangle.Java文件.

之后,我将只编译记录和密封的接口,而不编译Main.java.这是可能的,因为它们不依赖于Main.java.

最后,我跑了java Main米.这将运行Main.class文件,它不知道新的Triangle类,因为它是在我添加Triangle之前编译的.

这是执行default分支的地方,或者如果没有default分支,这是抛出MatchException的地方.

(请注意,MatchException部分仅适用于Switch表达式和带有箭头(->)的增强Switch语句.如果没有匹配的 case ,旧的School Switch语句根本不会做任何事情.)

另请参阅Java语言规范中的Execution of a switch StatementRun-Time Evaluation of switch Expressions.

Java相关问答推荐

使用ExecutorService时在ThreadFactory中触发自定义newThread函数

更新我们的一个文物后出现了严重的符号引用错误

无法找到符号错误—Java—封装

scanner 如何在执行hasNextLine一次后重新读取整个文件?

将数组整体转换为链接表

是否保证在事务性块的末尾标记违反约束?

R.id.main给我一个红色错误,无法解析MainActivity.java中的符号main

由于 list 中的权限错误,Android未生成

生成桥方法以解决具有相同擦除的冲突方法

为什么我的回收视图会显示重复的列表?

%This内置函数示例

Spring Boot&;Docker:无法执行目标org.springframework.boot:spring-boot-maven-plugin:3.2.0:build-image

Java Telnet客户端重复的IAC符号

Domino中不同的java.Protocol.handler.pkgs设置在XPages Java中导致错误

Quarkus:运行时出现EnumConstantNotPresentException

STREAMS减少部分结果的问题

带有可选部分的Java DateTimeForMatter

如何在Java中使用正则表达式拆分字符串

使用同步方法中的新线程调用同步方法

Spring Integration SFTP 连接失败 - 无法协商 kex 算法的密钥交换