我有一个使用Eclipse2022-03和OpenJDK 17的Java 17项目:
openjdk 17.0.2 2022-01-18
OpenJDK Runtime Environment Temurin-17.0.2+8 (build 17.0.2+8)
OpenJDK 64-Bit Server VM Temurin-17.0.2+8 (build 17.0.2+8, mixed mode, sharing)
我正在尝试使用新的Java 17开关特性,所以我尝试了一种方法:
return switch(testEnum) {
case foo -> newFoo();
case bar -> newBar();
}
效果很好。但是,我尝试这样做(因为值可能是null
):
return switch(testEnum) {
case foo -> newFoo();
case bar -> newBar();
case null -> newDefault();
}
Eclipse用红色标记null
,并说:
开关中的模式匹配是预览功能,默认情况下禁用。使用--启用-预览以启用
通过Maven编译生成:
[ERROR] /project/src/main/java/com/example/FooBar.java:[432,38] null in switch cases is a preview feature and is disabled by default.
[ERROR] (use --enable-preview to enable null in switch cases)
我的Maven项目有:
<properties>
<maven.compiler.release>17</maven.compiler.release>
</properties>
我知道编译器发行版设置不会被忽略;否则它将默认为Java 8(根据我的父POM),并且根本不允许模式匹配。
如果使用Java 17的模式匹配部分,空情况不是吗?我做错了什么?
发布于 2022-06-12 18:03:06
tl;dr
switch
表达式!=模式匹配与switch
您将switch
表达式的相对新特性与仍未发布的模式匹配特性与switch
混合在一起。
Java中的switch
特性经历了三个阶段的发展,其中两个阶段已经完成:
switch
语句(Java1中的原始特性)switch
表达式(☑️14+)switch
的❌模式匹配,包括case null
(在Java17、18、19和20中预览)不要将switch
表达式与模式匹配混为一谈
经典switch
要理解的是,历史上,Javaswitch
语句一直对null
检查怀有敌意。看这个问题,https://stackoverflow.com/q/10332132/642706。如图所示,代码如下:
switch (i) {
case null:
doSomething0();
break;
}
…是不可能的。
switch
表达式
当switch
表达式被添加到Java时,快速转发到Java 14。见https://openjdk.java.net/jeps/361。它允许您在第一个代码示例中看到的语法:
return switch(testEnum) {
case foo -> newFoo();
case bar -> newBar();
}
但是读JEP吧。没有提到null
-蟋蟀。
switch
中的模式匹配
快速前进,到https://openjdk.java.net/jeps/406。请注意,这是Java 17中的预览功能,而不是最后正式发布的特性。(要了解预览功能是如何工作的,请阅读https://openjdk.java.net/jeps/12。)
在JEP 406中,请注意它的第二个目标:允许在需要的时放松开关的历史无效敌意。
现在搜索该页面以查找“空”- 73命中!该页解释了以前Java语言的策略:
传统上,如果选择器表达式的计算结果为
switch
…,则NullPointerException
语句和表达式将抛出null
…。
请注意语句、原始switch
语法和附加表达式,以及代码中使用的新语法。在这两种情况下,null
检查都被禁止。
该页面将继续解释促使包含对空检查的支持的更改。阅读JEP的遗嘱详细信息。
其结果是,您可以在Java17中的case null
中使用switch
--但只有在您不择手段地使用时,才能启用预览功能。
仍在预览中,在Java 20中
在Java 20中,您也将不得不不择手段地使用激活预览功能。
当然还有两次提醒:
示例
让我们来看看这个代码示例。注意我们如何在这里使用普通的旧语法,而不使用->
。箭头操作符与我们在这里的讨论无关。
String x = null;
switch ( x )
{
case "starburst":
System.out.println( "Is starburst." );
break;
case null:
System.out.println( "Whoops, null." );
break;
default:
System.out.println( "Some other value found." );
break;
}
在Java 17中,默认情况下,在不启用预览特性的情况下,我们在编辑case null
代码时会出现此错误
在语言级别“17”不支持开关中的模式 将语言级别设置为17 (预览)-切换模式匹配
在启用Java 17中的预览功能之后,代码将毫无怨言地编译。它运行着:
喔,零。
发布于 2022-06-12 17:24:07
此命令行适用于我:
$ javac -version
javac 17.0.3
$ javac -source 17 -Xlint:preview --enable-preview org/kablambda/Main.java
org/kablambda/Main.java:10: warning: [preview] null in switch cases is a preview feature and may be removed in a future release.
case null -> "c";
^
1 warning
https://stackoverflow.com/questions/72596788
复制