Summary
Based on experiences with the several rounds of preview of pattern matching for switch, we propose a few improvements and simplifications. We also propose to make the feature final and permanent.
Problem
Based on the experiences with the previous round of preview of the feature, we currently propose four changes:
- parenthesized patterns should be dropped because they don't bring significant value in the current state of the feature; hence we propose to drop them.
- qualified enum constants should be allowed as case labels. This also impacts switch exhaustivity.
- the exhaustivity is newly defined to fix problems identified in the previous versions.
- inside a guard, variables declared outside of the guard cannot be assigned
The feature will be made final and permanent.
Solution
Parenthesized Patterns
The parenthesized patterns will be dropped. They will be removed from:
- the specification
- the implementation in javac
- the Trees API. The ParenthesizedPatternTree API interface has been marked as a preview feature since introduction, and therefore can be removed.
Qualified Enum Constants
Qualified enum constants will be allowed as case labels:
enum E1 { A, B, C; }
enum E2 { C, D, E; }
...
Object o = ...;
switch (o) {
case E1.A, E1.B, E1.C -> {}
case E2.C, E2.D -> {}
}
The existing unqualified enum constants will be preserved, in the existing context of an enum switch selector.
The exhaustivity determination will be naturally extended to include qualified enum constants: if all enum constants of an enum type are used in a set of switch constants, the set of switch constants is exhaustive for the given enum type.
New Definition of Exhaustivity
The current rules for switch exhaustivity see some obviously not-exhaustive switches as exhaustive. For example, code like:
public class Test {
private int test(R r) {
return switch (r) {
case R(A a, A b) -> 0;
case R(A a, B b) -> 0;
case R(B a, A b) -> 0;
case R(B(String s), B b) -> 0;
};
}
public sealed interface S permits A, B {}
public final class A implements S {}
public record B(Object o) implements S {}
public record R(S a, S b) {}
}
is considered to be exhaustive by the current rules, although the switch is obviously not exhaustive (does not cover R
with nested B
in the first component, where the nested component of the B
is not String
). New rules are proposed which are solving this problem.
Variable Assignment in Guards
The current specification allows to effectively re-assign final variable inside guards (please see here). The proposal is to disallow assignment to any variable inside case guards, unless the variable has been declared inside the guard.
Finalization of the Feature
The feature has been a preview feature for several releases. The proposal is to finalize it, making it final and permanent.
Specification
The specification draft is available for convenience here and is attached as" 20230509 Pattern Matching for switch and Record Patterns.pdf". Please note that, for technical reasons, the specification draft also includes changes for JEP-440 (https://openjdk.org/jeps/440), which are reviewed under CSR JDK-8304401.
The specdiff of API changes is available here and is attached as specdiff.00.zip. Please note that, for technical reasons, the specdiff also includes changes for JEP-440 (https://openjdk.org/jeps/440), which are reviewed under CSR JDK-8304401.
The feature will be made final and permanent.
- csr of
-
JDK-8300543 Compiler Implementation for Pattern Matching for switch
-
- Resolved
-