Hello! JLS requires (14.11.2) that the new "enhanced" switch statement (not expressions) must be exhaustive. In particular, for the switch over sealed abstract type, it's required to list all the permitted subtypes or provide a total/default branch. This is good. However, this means that from CFG point of view exactly one switch branch must always be visited. This is indeed so if we take a look at the bytecode: the synthetic default branch throws IncompatibleClassChangeError(). But compiler ignores this fact and refuses to compile the code like this (tried 18-ea+33-2077):
sealed interface Parent {} record A() implements Parent {} record B() implements Parent {} void test(Parent p) { int x; switch (p) { case A a -> x = 1; case B b -> x = 2; } System.out.println(x); // error: variable x might not have been initialized } I think this is a mistake that should be corrected: in this code, `x` should be considered as definitely assigned. I understand that the same reasoning does not apply for switch over enums, as for compatibility reasons, default behavior is to do nothing. However, for patterns, uninitialized `x` cannot appear after the switch, even if we recompile the sealed interface separately adding one more inheritor. I try to understand what's written in 16.2.9 regarding this [1]. Unfortunately, its current state looks confusing to me. Sorry if I'm missing something, as I'm not very experienced in reading chapter 16 of JLS. Nevertheless, it says: V is [un]assigned after a switch statement (14.11) iff all of the following are true: ... Original spec: - If there is no default label in the switch block, or if the switch block ends with a switch label followed by the } separator, then V is [un]assigned after the selector expression. Preview spec: - If the switch block covers the type of the selector expression, or if the switch block ends with a switch label followed by the } separator, then V is [un]assigned after the selector expression. It looks strange that "no default label" (~= non-exhaustive) was replaced with "covers the type" (= exhaustive). Was negation lost somewhere? In current state it looks like, all exhaustive switches (which is almost all switches), including ones with `default` branch cannot definitely assign a variable, which contradicts the previous state. If negation is actually lost, then the sample above should compile, as it's exhaustive. Sorry if this was already discussed. With best regards, Tagir Valeev [1] https://cr.openjdk.java.net/~gbierman/jep406/jep406-20210608/specs/patterns-switch-jls.html#jls-16.2.9