Summary
-------
Pattern matching for switch previewed in JDK 17 ([JEP 406](https://bugs.openjdk.java.net/browse/JDK-8213076)) and JDK 18 ([JEP 420](https://bugs.openjdk.java.net/browse/JDK-8273326)). It is proposed to preview for a third time in JDK 19, incorporating support for record patterns ([JEP 405](https://bugs.openjdk.java.net/browse/JDK-8260244)) and with adjustments based on feedback from preview rounds.
Problem
-------
More time is needed to gain experience with the pattern matching for switch feature. Following feedback from the first and second round of preview, some small amendments are being made.
Solution
--------
Pattern matching for switch will be a preview feature in JDK 19. The spec and compiler will be adjusted based on the current feedback.
Specification
-------------
The updated JLS draft for pattern matching for switch is attached as jep427+405-20220426.zip, and is also available for convenience [here](http://cr.openjdk.java.net/~gbierman/jep427+405/jep427+405-20220426/specs/patterns-switch-record-patterns-jls.html)
Note that the JLS draft also includes changes to support _Record Patterns_ ([JEP 405](https://openjdk.java.net/jeps/405)). An overview of how record patterns affect _Pattern Matching for switch_ is given in the [CSR for Record Patterns](https://bugs.openjdk.java.net/browse/JDK-8284529).
Other than support for record patterns, the third preview of _Pattern Matching for switch_ incorporates the following changes which are mostly informed by feedback from the second preview:
* The guarded pattern is dropped, and is replaced with a guard on pattern-based case labels. This means that nested patterns can no longer have their own guards.
* The guard separator is no longer '&&'. A new contextual keyword, 'when', is defined for this purpose.
* Both switch expressions and switch statements allow unconditional patterns.
* Null handling is now a property of the switch expression/statement, not of pattern matching.
* A new exception, `java.lang.MatchException`, is introduced for the cases where a switch is exhaustive at compile time, but not at run time. This can arise due to anomalous separate compilation:
* A sealed interface has a different set of permitted subtypes at run time than it had at compile time.
* An enum class has a different set of constants at run time than it had at compile time.
For example, this previous code:
Object o = ...;
switch (o) {
case null, String s && !"true".equals(s) -> {}
}
would now be written as:
Object o = ...;
switch (o) {
case null, String s when !"true".equals(s) -> {}
}
The API changes are attached as specdiff.00.zip, and are also available here:
http://cr.openjdk.java.net/~jlahoda/8282274/specdiff.00/overview-summary.html
The API changes mostly reflect the removal of the guarded patterns, the introduction of the guards on case labels, and the addition of `MatchException`.
The changes to the specification and API are a subject of change until the CSR is finalized.