首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有模式匹配的Java 17空情况

带有模式匹配的Java 17空情况
EN

Stack Overflow用户
提问于 2022-06-13 00:25:35
回答 2查看 1.3K关注 0票数 5

我有一个使用Eclipse2022-03和OpenJDK 17的Java 17项目:

代码语言:javascript
复制
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开关特性,所以我尝试了一种方法:

代码语言:javascript
复制
return switch(testEnum) {
  case foo -> newFoo();
  case bar -> newBar();
}

效果很好。但是,我尝试这样做(因为值可能是null):

代码语言:javascript
复制
return switch(testEnum) {
  case foo -> newFoo();
  case bar -> newBar();
  case null -> newDefault();
}

Eclipse用红色标记null,并说:

开关中的模式匹配是预览功能,默认情况下禁用。使用--启用-预览以启用

通过Maven编译生成:

代码语言:javascript
复制
[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项目有:

代码语言:javascript
复制
<properties>
  <maven.compiler.release>17</maven.compiler.release>
</properties>

我知道编译器发行版设置不会被忽略;否则它将默认为Java 8(根据我的父POM),并且根本不允许模式匹配。

如果使用Java 17的模式匹配部分,空情况不是吗?我做错了什么?

EN

回答 2

Stack Overflow用户

发布于 2022-06-13 02: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。如图所示,代码如下:

代码语言:javascript
复制
switch (i) {
    case null:
        doSomething0();
        break;    
}

…是不可能的。

switch表达式

switch表达式被添加到Java时,快速转发到Java 14。见https://openjdk.java.net/jeps/361。它允许您在第一个代码示例中看到的语法:

代码语言:javascript
复制
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中

https://en.wikipedia.org/wiki/Orson_Welles_Paul_Masson_advertisements#1978:_Original_ad%E2%80%94Beethoven,_Emerald_Dry

在Java 20中,您也将不得不不择手段地使用激活预览功能

当然还有两次提醒:

  • 预览功能不应用于关键应用程序的生产。
  • 预览功能可能会改变。这就是他们的目的,收集导致改变的反馈和建议。

示例

让我们来看看这个代码示例。注意我们如何在这里使用普通的旧语法,而不使用->。箭头操作符与我们在这里的讨论无关。

代码语言:javascript
复制
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中的预览功能之后,代码将毫无怨言地编译。它运行着:

喔,零。

票数 9
EN

Stack Overflow用户

发布于 2022-06-13 01:24:07

此命令行适用于我:

代码语言:javascript
复制
$ 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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72596788

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档