import java.util.List; class Main { void dominance(Object o, Integer ii, String s, Day d) { // A switch label that has a pattern case label element p dominates another switch label that has a pattern case label element q if p dominates q switch (o) { case List n: System.out.println("num"); break; case List i: System.out.println("int"); break; default: System.out.println("def"); break; } String str; str = switch (o) { case List n -> "num"; case List i -> "int"; default -> "def"; }; switch (o) { case Number n: System.out.println("num"); break; case Integer i: System.out.println("int"); break; default: System.out.println("def"); break; } str = switch (o) { case Number n -> "num"; case Integer i -> "int"; default -> "def"; }; // Dominance permits a guarded pattern to be followed by its unguarded form: switch (o) { case Integer o1 when o1 != null: System.out.println("num"); break; case Integer i: System.out.println("int"); break; default: System.out.println("def"); break; } str = switch (o) { case Integer o1 when o1 != null -> "num"; case Integer i -> "int"; default -> "def"; }; switch (o) { case Integer i: System.out.println("int"); break; case Integer o1 when o1 != null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (o) { case Integer i -> "num"; case Integer o1 when o1 != null -> "int"; default -> "def"; }; switch (o) { case Integer o1 when o1 > 5: System.out.println("int"); break; case Integer o2 when o2 != null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (o) { case Integer o1 when o1 > 5 -> "num"; case Integer o2 when o2 != null -> "int"; default -> "def"; }; switch (o) { case Number i when Math.random() > 0.5: System.out.println("int"); break; case Integer o2 when o2 != null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (o) { case Number i when Math.random() > 0.5 -> "num"; case Integer o2 when o2 != null -> "int"; default -> "def"; }; switch (o) { case Integer i when true: System.out.println("int"); break; case Integer o2 when o2 != null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (o) { case Integer i when true -> "num"; case Integer o2 when o2 != null -> "int"; default -> "def"; }; // A switch label that has a pattern case label element p that is total for the type of the selector expression // of the enclosing switch statement or switch expression dominates a switch label that has a null case label element. switch (ii) { case Object obj: System.out.println("int"); break; case null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (ii) { case Object obj -> "num"; case null -> "int"; default -> "def"; }; switch (ii) { case Object obj, null: System.out.println("int"); break; default: System.out.println("def"); break; } str = switch (ii) { case Object obj -> "int"; default -> "def"; }; switch (ii) { case Integer i when true: System.out.println("int"); break; case null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (ii) { case Integer i when true -> "int"; case null -> "int"; default -> "def"; }; switch (ii) { case Integer i when Math.random() > 0.5: System.out.println("int"); break; case null: System.out.println("num"); break; default: System.out.println("def"); break; } str = switch (ii) { case Integer i when Math.random() > 0.5 -> "int"; case null -> "int"; default -> "def"; }; // A switch label that has a pattern case label element p dominates another switch label that has a constant case label element c // if either of the following is true: //the type of c is a primitive type and its wrapper class is a subtype of the erasure of the type of p. //the type of c is a reference type and is a subtype of the erasure of the type of p. switch (ii) { case Integer i: break; case 1: case 2: break; } str = switch (s) { case String sss -> "s"; case "1", "2" -> "1"; }; // any type of pattern (including guarded patterns) dominates constant cases switch (d) { case Day dd: break; case MONDAY: break; } str = switch (ii) { case Integer in when in != null -> ""; case 1 -> ""; default -> ""; }; switch (d) { case Day dd when true: break; case MONDAY: break; } } void completeness(Day d, I i, I2 i2, I3 i3, AorBorC abc, J1 j, II ii) { // old style switch, no completeness check switch (d) { case MONDAY, TUESDAY -> System.out.println("ok"); } // If the type of the selector expression is an enum type E String str; switch (d) { case Day dd when dd != null: System.out.println("ok"); case MONDAY: System.out.println("mon"); } switch (d) { case Day dd when dd != null: System.out.println("ok"); } str = switch (d) { case MONDAY, TUESDAY -> System.out.println("ok"); }; str = switch (d) { case MONDAY, TUESDAY, WEDNESDAY -> "ok"; }; str = switch (d) { case MONDAY, TUESDAY -> "ok"; }; switch (d) { case Day dd when true: System.out.println("ok"); default: // blah blah blah System.out.println("mon"); } ; switch (d) { case Day dd when dd != null: System.out.println("ok"); default: System.out.println("mon"); } ; // If the type of the selector expression, T, names a sealed interface or a sealed class that is abstract switch (i) { case Sub1 s1: System.out.println("ok"); break; case Sub2 s2: System.out.println("ok"); break; case Sub3 s3: System.out.println("ok"); break; } str = switch (i) { case Sub1 s1 -> "ok"; case Sub2 s2 -> "ok"; case Sub3 s3 when true -> "ok"; }; switch (i) { case Sub1 s1: System.out.println("ok"); break; case Sub2 s2: System.out.println("ok"); break; } str = switch (i) { case Sub1 s1 -> "ok"; case Sub2 s2 -> "ok"; } ; switch (i) { case Sub1 s1: System.out.println("ok"); break; case Sub2 s2: System.out.println("ok"); break; case Sub4 s4: System.out.println("ok"); break; case Sub6 s6: System.out.println("ok"); break; } str = switch (i) { case Sub1 s1 -> "ok"; case Sub2 s2 -> "ok"; case Sub4 s4 -> "ok"; case Sub6 s6 -> "ok"; }; switch (i) { case Sub1 s1: break; case Sub2 s2 when Math.random() > 0.5: break; case Sub3 s3: break; } str = switch (i) { case I in when in != null -> "ok"; }; switch (i3) { case Sub9 s when true: break; case Sub11 s: break; case Sub12 s when true: break; } str = switch (abc) { case A a -> "1"; case B b -> "2"; case C c -> "3"; }; str = switch (abc) { case A a -> "1"; case C c -> "2"; case AorB ab -> "3"; case BorC bc -> "4"; }; switch (j) { case R1 r1: break; case R2 r2: break; } // If the type of the selector expression, T, is not an enum type and also does not name a sealed interface or a sealed class that is abstract switch (i2) { case Sub7 s1: System.out.println("ok"); break; case Sub8 s2: System.out.println("ok"); break; } str = switch (i2) { case Sub7 s1 -> "ok"; case Sub8 s2 -> "ok"; }; // empty switches switch (d) { } str = switch (d) { }; switch (i) { } str = switch (i) { }; switch (i2) { } str = switch (i2) { }; // 'case AA' is redundant brach here as 'AA' is not castable to II, so the code compiles correctly switch (ii) { case BB b -> { } } } } sealed interface I { } enum Day { MONDAY, TUESDAY, WEDNESDAY } final class Sub1 implements I { } final class Sub2 implements I { } sealed class Sub3 implements I { } final class Sub4 extends Sub3 { } final class Sub5 { } final class Sub6 extends Sub3 { } interface I2 { } class Sub7 implements I2 { } class Sub8 implements I2 { } sealed interface I3 { } final class Sub9 implements I3 { } sealed abstract class Sub10 implements I3 { } final class Sub11 extends Sub10 { } final class Sub12 extends Sub10 { } sealed interface AorBorC { } sealed interface AorB extends AorBorC { } sealed interface BorC extends AorBorC { } sealed interface AorC extends AorBorC { } final class A implements AorB, AorC { } final class B implements AorB, BorC { } final class C implements AorC, BorC { } sealed interface J1 { } sealed interface J2 extends J1 permits R1 { } record R1() implements J1, J2 { } record R2() implements J1 { } sealed interface II { } final class AA implements II { } final class BB implements II { }