eclipse 具有模式匹配的Java 17空大小写

jv4diomz  于 2022-11-04  发布在  Eclipse
关注(0)|答案(2)|浏览(174)

我有一个使用Eclipse 2022-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下加上红色下划线,并显示:
Switch中的模式匹配是一个预览功能,默认情况下禁用。使用--enable-preview可启用
通过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>

我知道编译器的发布设置没有被忽略;否则它将默认为Java8(根据我的父POM),并且根本不允许模式匹配。
模式匹配的空情况不是Java 17的一部分吗?我做错了什么?

x9ybnkn6

x9ybnkn61#

tl;dr

👉 switch表达式!=与switch匹配的模式
您混淆了 * switch表达式 * 这一相对较新的特性和 * 模式匹配switch * 这一尚未发布的特性。
Java中的switch特性经历了3个阶段的发展,其中两个阶段已经完成:

  • x1️ m5n1x语句(Java 1中的原始特性)
  • x1️ m6n1x表达式(Java 14+)
  • 针对switch的模式匹配,包括case null(在Java 17、18、19和20中预览)

不要将switch表达式与模式匹配合并

经典switch
要知道,Java switch语句一直以来都对null检查持敌对态度。请参见这个问题How to use null in switch。如图所示,代码如下:

switch (i) {
    case null:
        doSomething0();
        break;    
}

......不可能。

switch表达式

快进到Java 14,此时switch表达式被添加到Java中。请参见JEP 361: Switch Expressions。这允许您在第一个代码示例中看到的语法:

return switch(testEnum) {
  case foo -> newFoo();
  case bar -> newBar();
}

但是看看JEP,没有提到蟋蟀。

switch的模式匹配

进一步快进到JEP 406: Pattern Matching for switch (Preview)。请注意,这是Java 17中的预览特性,而不是正式发布的最终特性。(要了解预览特性如何工作,请阅读JEP 12: Preview Features。)
👉 在JEP 406中,请注意它的第二个目标:允许在需要时放松开关的历史零敌意
现在搜索该页面中的“null”-- 73个匹配项!该页面解释了Java语言以前的策略:
传统上,如果选择器表达式的计算结果为null,则switch语句和表达式将引发NullPointerException...
注意 statements(原始的switch语法)和 expressions(代码中使用的新语法)的提及,在这两种情况下,null检查都被禁止。
该页面继续解释了促使包含对空检查的支持的变化。阅读JEP以获得将写的细节。
👉 结果是,您可以在Java 17的switch中使用case null--但前提是您必须启用预览特性

仍在预览中,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中启用预览特性后,代码可以毫无问题地进行编译,并运行:
哎呦,空。

w8f9ii69

w8f9ii692#

以下命令行适用于我:

$ 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

相关问题