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

14.11.1.2: Incorrect semantics of switch with null labels

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • 19
    • None
    • specification
    • b26

      In Java 19, JEP 427 "Pattern Matching for switch (Third Preview)" adds a new null case label. When it appears alongside a type pattern, not only should the case label apply when the value of the selector expression is null but the pattern variable should be initialised with null.

      This is handled by resolving the switch label to use ANY patterns. The specification states that:

      case null, String s

      is resolved to

      case ANY(String s)

      So it will match when the selector expression is the null reference. But this is incorrect as the label `case String s` can also be compiled to `case ANY(String s)` (when the selector expression is of type String) and this should not match when the selector expression is the null reference.

      The correct resolving of the label is:

      case null, ANY(String s)

      and then the semantics of switch should look for a null constant and then match the pattern also supported by the label. (This will then have the side-effect of initialising the String s pattern variable.)

      In addition, the semantics of pattern matching for ANY patterns needs correction. The specification states that any value matches an any pattern. But this incorrectly means that a switch such as

      switch(o) {
          case null, String s -> ...
          case Object o -> ...
      }

      With the proposed rules for resolving these patterns, this switch is resolved to:

      switch(o) {
          case null, ANY(String s) -> ...
          case ANY(Object o) -> ...
      }

      But if o is the result of expression `new Object()`, it should be the second label that matches. The rules for pattern matching with an any pattern should read:

      - The null reference *matches* an any pattern.

          The pattern variable declared by the any pattern is initialized to the null reference.

      - A value *v* that is not the null reference *matches* an any pattern of type
          *T* if *v* can be cast to *T* without raising a `ClassCastException`; and
          *does not match* otherwise.
          
          If *v* matches, then the pattern variable declared by the any pattern is
          initialized to *v*.
          
          If *v* does not match, then the pattern variable declared by the any
          pattern is not initialized.

            gbierman Gavin Bierman
            gbierman Gavin Bierman
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: