Question 6
`Shape` is sealed and permits exactly `Circle` and `Square`, and the switch in `kind` has a case for each of them, with no `default`. What is the result of compiling and running this program?
```java
public class Main {
sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double side) implements Shape {}
static String kind(Shape sh) {
return switch (sh) {
case Circle c -> "circle";
case Square s when s.side() > 0 -> "square";
};
}
public static void main(String[] args) {
System.out.println(kind(new Circle(2.0)));
}
}
```
A. Compilation fails: a guard is not permitted on a case label in a switch over a sealed type
Invents a rule: a guard is perfectly legal on a case label here; adding an unguarded `case Square s` after the guarded case, or a `default`, makes this same switch compile.
B. circle
Assumes the program compiles because every permitted subtype is mentioned somewhere in the switch; being mentioned is not the same as being covered, and the guard is exactly what breaks the link.
C. An exception is thrown at runtime: java.lang.MatchException
Assumes the coverage gap is discovered at run time when a value slips past every case; the compiler will not let a non-exhaustive switch expression get that far, so there is no run time.
D. Compilation fails: the switch expression does not cover all possible input valuesCorrect answer
A case carrying a `when` guard is a conditional match, so the compiler refuses to count it for coverage; coverage of Shape then rests on `case Circle c` alone, which does not cover Square, so javac rejects the switch expression as not exhaustive (JLS 25 14.11.1.1).
Explanation
Trace: a case label carrying a `when` guard is a *conditional* match, so the compiler refuses to count it when it computes coverage — it cannot prove `s.side() > 0` holds. Coverage of `Shape` therefore rests on `case Circle c` alone, which does not cover `Square`, and the switch expression is not exhaustive. javac rejects it with `error: the switch expression does not cover all possible input values`. The `Circle` argument in `main` is irrelevant: exhaustiveness is a compile-time property of the switch, not of the value that reaches it.
Why the others are wrong:
`circle` assumes the program compiles because every permitted subtype is mentioned somewhere in the switch. Being mentioned is not the same as being covered — the guard is exactly what breaks the link.
`Compilation fails: a guard is not permitted on a case label in a switch over a sealed type` invents a rule. Guards are perfectly legal here; adding `case Square s -> "square";` after the guarded case, or a `default`, makes this same switch compile.
`An exception is thrown at runtime: java.lang.MatchException` assumes the gap is discovered at run time when a value slips past every case. The compiler will not let a non-exhaustive switch *expression* get that far, so there is no run time.
Exam tip: a guarded case never contributes to exhaustiveness. The idiom is to guard a case and then follow it with the same unguarded pattern as a fallback (`case Square s when s.side() > 0 -> ...; case Square s -> ...;`). Reverse trap: this bites only switch *expressions* and pattern switch *statements*; the compiler's message points at the `switch` keyword, not at the guard, so students hunt for a missing subtype that is right there on the screen.