Home > Net >  Pattern Matching for instanceof throwing a confusing error: expression type Triple is a subtype of p
Pattern Matching for instanceof throwing a confusing error: expression type Triple is a subtype of p

Time:01-02

I have Java 19, and I am attempting to do some simple pattern-matching on a record that I created. However, Java is giving me a very confusing compilation error. Here is the simplest example I could make that causes the error.

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");

      }

   }

}

And here is the error that it gives me when I try to run/compile.

$ 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

Surprisingly enough, googling this error showed up nothing useful. I am so used to punching in an error and immediately seeing the problem. I imagine that it is because this feature is so new.

Anyways, the closest thing I could find is a bug that is related, but definitely not the same issue that I am dealing with.

Finally, here is the relevant info about my java version.

$ 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

CodePudding user response:

Java is just being "nice": it recognizes that the test will always succeed (because input is known to be a Triple, which is already a subtype of the test type Triple), so it produces an error telling you that you're doing something useless (with a roundabout message).

This is the same idea that makes

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

an error: there is a useless piece of code that might indicate (serious) programmer error, so the compiler forces you to rethink the code.

The relevant section of the JLS is 15.20.2, which says

InstanceofExpression:

  • ...
  • RelationalExpression instanceof Pattern

...

The following rules apply when instanceof is the pattern match operator:

  • ...
  • If the type of the RelationalExpression is a subtype of the type of the Pattern, then a compile-time error occurs.

I.e. this is indeed an intended part of the language and not just a compiler bug or something.

CodePudding user response:

It looks like you are trying to use the new instanceof pattern matching feature introduced in Java 14.

The error message expression type Triple is a subtype of pattern type Triple means that the type of the expression on the left side of the instanceof operator is a subtype of the pattern type on the right side of the instanceof operator.

In this case, the type of the expression input is Triple, and the pattern type is also Triple, so the condition should be evaluated as true, and the code inside the block should be executed.

It looks like the compiler is not recognizing this, and is giving you an error.

One possible reason for this error is that you are using an older version of the Java compiler that does not support the instanceof pattern matching feature.

You can check the version of the Java compiler by running the javac --version command.

If you are using a version of the Java compiler that is older than 14, you will need to update it to a newer version in order to use the instanceof pattern matching feature.

  • Related