Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8287884

javac compilation fails instanceof pattern matching with two ifs

XMLWordPrintable

    • generic
    • generic

      ADDITIONAL SYSTEM INFORMATION :
      Linux 4.15.0-180-generic #189-Ubuntu
      javac 17.0.3

      A DESCRIPTION OF THE PROBLEM :
      The following snippet does not compile with javac:

      class Instanceof {
          static void doesNotWork(Object o) {
              if (o == null) {
                  throw new Error();
              } else if (!(o instanceof String s)) {
                  throw new Error();
              }
              System.out.println(s); // error here
          }
      }

      cannot find symbol
      symbol: variable s
      location: class Instanceof

      According to the specification it seems that s should be visible after the if block.
      I believe this is a bug in javac.
      FYI, the ecliple compiler does accept this code.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a file named Instanceof.java with contents:
      ---
      class Instanceof {
          static void doesNotWork(Object o) {
              if (o == null) {
                  throw new Error();
              } else if (!(o instanceof String s)) {
                  throw new Error();
              }
              System.out.println(s); // error here
          }
      }
      ---
      Attempt to compile this file using javac.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The file compiles.
      ACTUAL -
      The file does not compile.
      The error is "cannot find symbol".

      ---------- BEGIN SOURCE ----------
      class Instanceof {
          static void doesNotWork(Object o) {
              if (o == null) {
                  throw new Error();
              } else if (!(o instanceof String s)) {
                  throw new Error();
              }
              System.out.println(s); // error here
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Using an explicit else block solves the problem
         if (o == null) {
              throw new Error();
          } else if (!(o instanceof String s)) {
              throw new Error();
          } else {
              System.out.println(s);
          }
      as does not using else if at all.
          if (o == null) {
              throw new Error();
          }
          if (!(o instanceof String s)) {
              throw new Error();
          }
          System.out.println(s);
      It also works with exactly one if.
          if (o == null || !(o instanceof String s)) {
              throw new Error();
          }
          System.out.println(s);

      FREQUENCY : always


            gbierman Gavin Bierman
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: