import java.util.*;
class Main {
static class X {
int f() { return 0; }
}
int switchTestResolve(Object o) {
int i1 = switch(o) {
case X x -> x.f();
default -> 1;
};
int i2 = switch(o) {
case null, X x -> x.f();
default -> 1;
};
int i3 = switch(o) {
case X x, null -> x.f();
default -> 1;
};
int i4 = switch(o) {
case String s, X x -> x.f();
default -> 1;
};
int i5 = switch(o) {
case String s, X x -> x.f();
default -> 1;
};
int i6 = switch(o) {
case X x, String s -> x.f();
default -> 1;
};
return i1 + i2 + i3 + i4 + i5 + i6;
}
void checkSwitchSelectorType(boolean b, double d, int[] array) {
switch (b) {
case true:
System.out.println("true");
break;
case false:
System.out.println("false");
break;
}
String str;
str = switch(d) {
case 1 -> "ok";
case 2 -> "not ok";
};
switch (array) {
case int[] arr:
System.out.println("true");
break;
}
str = switch (array) {
case int[] arr -> "true";
};
// intersection type
var values = List.of("foo", 3, 4.0);
for (var value : values) {
switch (value) {
case Integer i -> System.out.println("integer !");
case String s -> System.out.println("string !");
case Object o -> System.out.println("object !");
}
}
}
void constLabelAndSelectorCompatibility(Number n, CharSequence c, Integer i, String s) {
switch (n) {
case 1:
System.out.println("ok");
}
String str;
str = switch (n) {
case 1 -> "ok";
default -> "not ok";
};
switch (c) {
case "ok":
System.out.println("ok");
}
str = switch (c) {
case "ok" -> "ok";
default -> "not ok";
};
switch (i) {
case '1':
System.out.println("ok");
}
str = switch (i) {
case '1' ->"ok";
default -> "not ok";
};
switch (i) {
case 1:
System.out.println("ok");
}
str= switch (i) {
case 1 -> "ok";
default -> "not ok";
};
switch (s) {
case "null" :
System.out.println("null");
break;
default:
System.out.println("s");
}
str = switch (s) {
case "null" -> "null";
default -> "s";
};
}
void incompatibleNullLabelAndSelector(int i) {
switch (i) {
case null:
System.out.println("ok");
}
String str;
str = switch (i) {
case null -> "ok";
default -> "not ok";
};
}
void defaultAlwaysCompatible(int i) {
switch (i) {
case 1, default:
System.out.println("ok");
}
String str;
str = switch (i) {
case 1, default -> "ok";
};
}
void patternsCompatibilty(I i, Object o, List extends Number> list1, List list2) {
switch (i) {
case Sub1 s2:
System.out.println("s1");
break;
case Sub5 s5:
System.out.println("s5");
default:
System.out.println("s");
}
String str;
str = switch (i) {
case Sub1 s2 -> "s1";
case Sub5 s5 -> "s5";
default -> "s";
};
switch (i) {
// total pattern
case Object oo:
System.out.println("s1");
}
str = switch (i) {
// total pattern
case Object oo -> "s1";
};
// unsafe casts
switch (list1) {
case List l:
break;
}
switch (list2) {
case List extends Number> l:
break;
}
switch (o) {
case List ll:
break;
case default:
break;
}
switch (list1) {
case Object oo:
break;
}
// null selector
switch (null) {
case null:
break;
default:
break;
};
str = switch (null) {
case null -> "null";
default -> "def";
};
switch (o) {
case int ii: break;
default: break;
}
str = switch (o) {
case int ii -> "";
default -> "";
};
}
private static final int constant = 1;
void duplicateLabels(Integer i) {
String str;
switch (i) {
case 1:
break;
case Main.constant:
break;
}
str = switch (i) {
case 1 -> "";
case constant -> "";
};
// A switch label may not use more than one default label
switch (i) {
case 1, default:
System.out.println("s1");
break;
default:
System.out.println("s");
}
str = switch (i) {
case 1, default -> "s1";
default -> "s";
};
switch (i) {
case default:
System.out.println("s1");
break;
case default:
System.out.println("s");
}
str = switch (i) {
case default -> "s1";
case default -> "s";
};
// A switch label may not have more than one default case label element
switch (i) {
case default, default:
System.out.println("s");
}
str = switch (i) {
case default, default -> "s";
};
// A switch label may not have more than one null case label element.
switch (i) {
case 1, null:
System.out.println("s");
case null:
System.out.println("null");
}
str = switch (i) {
case 1, null -> "s";
case null -> "null";
};
}
void fallThroughToPatterns(Object o, Integer ii) {
// If a switch label has a null case label element then if the switch label also has any pattern case element labels, t
// they must be type patterns (14.30.1).
switch (o) {
case Integer i && i != null, null:
break;
case default:
break;
}
String str;
str = switch (o) {
case Integer i && i != null, null -> "s";
default -> "null";
};
switch (o) {
case null, Integer i && i != null:
break;
case default:
break;
}
str = switch (o) {
case null, Integer i && i != null -> "s";
default -> "null";
};
switch (o) {
case null: case Integer i && i != null:
break;
case default:
break;
}
str = switch (o) {
case null: case Object i && i != null: yield "sfds";
};
str = switch (o) {
case null, Object i && i != null -> "sfds";
case default -> "fsd";
};
switch (o) {
case null: case Integer i:
break;
case default:
break;
}
str = switch (o) {
case null: case Integer i: yield "s";
case default: yield "d";
};
// A switch label may not have more than one pattern case label element.
switch (o) {
case Integer i, Long l && l != null: System.out.println("s");
default: System.out.println("null");
}
str = switch (o) {
case Integer i, Long l && l != null -> "s";
default -> "null";
};
switch (o) {
case Integer i: case Long l: System.out.println("s");
default: System.out.println("null");
}
str = switch (o) {
case Integer i: case Long l: yield "s";
default: yield "res";
};
// A switch label may not have both a pattern case label element and a default case label element.
switch (o) {
case Integer i, default: System.out.println("s");
}
str = switch (o) {
case Integer i, default -> "s";
};
switch (o) {
case default, Integer i: System.out.println("s");
}
str = switch (o) {
case default, Integer i -> "s";
};
switch (o) {
case Integer i: case default: System.out.println("s");
}
str = switch (o) {
case Integer i: case default: yield "s";
};
switch (ii) {
case Integer i && i > 1:
default: System.out.println("null");
}
str = switch (ii) {
case Integer i && i > 1:
default: yield "null";
};
// If a switch label has a constant case label element then if the switch label also has other case element labels
// they must be either a constant case label element, the default case label element, or the null case label element.
switch (ii) {
case 1, Integer i1 && i1 > 5:
System.out.println("s1");
break;
default: System.out.println("null");
}
str = switch (ii) {
case 1, Integer i1 && i1 > 5 -> "s1";
default -> "null";
};
switch (ii) {
case Integer i1 && i1 > 5, 1:
System.out.println("s1");
break;
default: System.out.println("null");
}
str = switch (ii) {
case Integer i1 && i1 > 5, 1 -> "s1";
default -> "null";
};
switch (ii) {
case 1, 2: case null, Integer i1 && i1 > 5:
System.out.println("s1");
break;
default: System.out.println("null");
}
// more complex case
switch (ii) {
case 1, null, Integer i1 && i1 > 5, default:
System.out.println("s1");
break;
}
str = switch (ii) {
case 1, null, Integer i1 && i1 > 5, default -> "s1";
};
str = switch (ii) {
case 1, 2, Integer i1 && i1 > 5: case null:
System.out.println("s1");
yield "s1";
default: yield "def";
};
/**
* It is a compile-time error if there is a statement in a switch block that consists of switch-labeled statement groups
* for which both of the following are true:
* It is labeled with a switch label that has a pattern case label element whose pattern introduces a pattern variable.
* There is a statement preceding it in the switch block and that statement can completely normally (14.22).
*/
switch (o) {
case default:
System.out.println("def");
case Float d:
System.out.println("float");
}
switch (o) {
case null, Integer i:
if (o != null) {
throw new IllegalArgumentException("");
}
case Float d:
System.out.println("float");
}
switch (o) {
case null:
if (o != null) {
throw new IllegalArgumentException("");
}
break;
case Float d:
System.out.println("float");
default:
System.out.println("ok");
}
// switch expressions
str = switch (o) {
case null, Integer i:
if (o != null) {
throw new IllegalArgumentException("");
}
case Float d:
System.out.println("float");
default:
yield "1";
};
str = switch (o) {
case null:
if (o != null) {
throw new IllegalArgumentException("");
}
yield "1";
case Float d:
System.out.println("float");
default:
yield "1";
};
}
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 && 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 && o1 != null -> "num";
case Integer i -> "int";
default -> "def";
};
switch (o) {
case (Integer i):
System.out.println("int");
break;
case Integer o1 && o1 != null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case (Integer i) -> "num";
case Integer o1 && o1 != null -> "int";
default -> "def";
};
switch (o) {
case (Integer o1 && o1 > 5):
System.out.println("int");
break;
case Integer o2 && o2 != null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case (Integer o1 && o1 > 5) -> "num";
case Integer o2 && o2 != null -> "int";
default -> "def";
};
switch (o) {
case (Number i && false):
System.out.println("int");
break;
case Integer o2 && o2 != null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case (Number i && false) -> "num";
case Integer o2 && o2 != null -> "int";
default -> "def";
};
switch (o) {
case (Integer i && true):
System.out.println("int");
break;
case (Integer o2 && o2 != null):
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case (Integer i && true) -> "num";
case (Integer o2 && 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, null -> "int";
default -> "def";
};
switch (ii) {
case (Integer i && 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 && true) -> "int";
case null -> "int";
default -> "def";
};
switch (ii) {
case ((Integer i && false)):
System.out.println("int");
break;
case null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (ii) {
case ((Integer i && false)) -> "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";
};
// !!! here are some contradictory examples with spec, but javac still compiles them. To be discussed in the mailing list
// at least for now it's look quite logical if we have a total pattern in a switch label, and following constant switch label,
// then the first switch label dominates the second one.
switch (d) {
case Day dd: break;
case MONDAY: break;
}
str = switch (ii) {
case Integer in && in != null -> "";
case 1 -> "";
case default -> "";
};
switch (d) {
case (Day dd && true): break;
case MONDAY: break;
}
}
void completeness(Day d, I i, I2 i2, I3 i3) {
// 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 && dd != null:
System.out.println("ok");
case MONDAY:
System.out.println("mon");
};
switch (d) {
case Day dd && 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, default -> "ok";
};
switch (d) {
case ((Day dd && true)):
System.out.println("ok");
default: // blah blah blah
System.out.println("mon");
};
switch (d) {
case ((Day dd && 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 && 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 && false):
break;
case Sub3 s3:
break;
}
str = switch(i) {
case I ii && ii != null -> "ok";
};
switch (i3) {
case (Sub9 s && true):
break;
case Sub11 s:
break;
case Sub12 s && true:
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) {
};
}
}
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 {
}