instanceof 的模式匹配抛出令人困惑的错误:表达式类型 Triple 是模式类型 Triple 的子类型

问题描述 投票:0回答:3

我有 Java 19,我正在尝试对我创建的记录进行一些简单的模式匹配。然而,Java 给了我一个非常令人困惑的编译错误。这是我可以做的导致错误的最简单的例子。

public class ExpressionTypeIsASubsetOfPatternType
{

   public record Triple(int a, int b, int c) {}

   public static void main(String[] args)
   {

      System.out.println("Java Version = " + System.getProperty("java.version"));

      final Triple input = new Triple(1, 2, 3);

      if (input instanceof Triple t)
      {

         System.out.println("Made it here");

      }

   }

}

这是当我尝试运行/编译时它给我的错误。

$ java ExpressionTypeIsASubsetOfPatternType.java
ExpressionTypeIsASubsetOfPatternType.java:15: error: expression type Triple is a subtype of pattern type Triple
      if (input instanceof Triple t)
                ^
1 error
error: compilation failed

令人惊讶的是,谷歌搜索此错误没有显示任何有用的信息。我已经习惯了输入错误并立即发现问题。我想这是因为这个功能太新了。

无论如何,我能找到的最接近的东西是一个相关的bug,但绝对不是我正在处理的同一问题。

最后,这是我的java版本的相关信息。

$ java --version
openjdk 19 2022-09-20
OpenJDK Runtime Environment (build 19+36-2238)
OpenJDK 64-Bit Server VM (build 19+36-2238, mixed mode, sharing)
$ javac --version
javac 19
java pattern-matching instanceof java-record
3个回答
6
投票

HTNW 的答案 是正确的响应,但我发现编译器的这种行为并不理想,因为它没有考虑空引用。这里有一些不一致之处:

String s = null;
if (s instanceof String) {}
String s = null;
if (s instanceof String string) {}

第一个选项将编译,第二个选项将给出错误“模式类型‘字符串’与表达式类型相同”。这意味着

instanceof
可以用作空检查,但如果使用模式匹配则不能。没有意义。


3
投票

Java 只是“很好”:它认识到测试将always成功(因为

input
已知是
Triple
,它已经是测试类型
Triple
的子类型),因此它产生一个错误告诉您您正在做一些无用的事情(带有迂回消息)。

这也是同样的想法

void foo() {
  return;
  return; // error: unreachable statement
}

错误:有一段无用的代码可能表明(严重的)程序员错误,因此编译器迫使您重新考虑代码。

JLS 的相关部分是15.20.2,其中写着

表达式实例

  • ...
  • 关系表达式
    instanceof
    模式

...

instanceof
是模式匹配运算符时,适用以下规则:

  • ...
  • 如果 RelationalExpression 的类型是 Pattern 类型的子类型,则会发生编译时错误。

即这确实是该语言的预期部分,而不仅仅是编译器错误或其他东西。


0
投票

我完全同意@kingds的观点,即我们在执行空检查时不能使用模式匹配是没有意义的。

我遇到了同样的错误,我的愚蠢修复是将操作数向下转换为

Object
:

if ((Object)input instanceof Triple t) {
    // ...
}

现在 Java 很高兴,因为它正在测试某些泛型

Object
是否可能是
Triple
实例。

© www.soinside.com 2019 - 2024. All rights reserved.