🪆 Enums, Records & Nested Types · Intermediate

Enums in switch in Java

Exhaustive switch expressions over enums.

🧩 The mysteryYour code handles RED, GREEN and BLUE. A teammate adds YELLOW. Can Java tell you every place you forgot to handle it — before you ship?

Switch with bare names

Switch on an enum and write case labels with just the constant names — case RED, not case Color.RED (the qualified form is also allowed since Java 21). A switch expression produces a value from each case.

String hex = switch (color) {
    case RED -> "#f00";
    case GREEN -> "#0f0";
    case BLUE -> "#00f";
};
🔮 Predict it

One case missing

d is UP at runtime, and UP is handled. What happens?

enum Dir { UP, DOWN, LEFT }
void main() {
    Dir d = Dir.UP;
    int dy = switch (d) {
        case UP -> -1;
        case DOWN -> 1;
    };
    System.out.println(dy);
}
  1. -1
  2. Compile error
  3. 0
Show the answer

A switch expression must produce a value for every possible input. The compiler doesn't care what d holds at runtime: LEFT isn't covered and there's no default, so it won't compile.

Exhaustive: a feature, not a chore

Cover every constant and you need **no default. Better: when someone adds a new constant, every such switch becomes a compile error** that points at exactly what to update. (If old compiled code meets the new constant at runtime, Java 21+ throws MatchException.)

🔮 Predict it

Old-style colon cases

Classic case X: labels, no break. What prints?

enum Level { LOW, MID, HIGH }
void main() {
    switch (Level.MID) {
        case LOW: System.out.print("L");
        case MID: System.out.print("M");
        case HIGH: System.out.print("H");
    }
    System.out.println();
}
  1. M
  2. MH
  3. LMH
  4. Compile error
Show the answer

Colon cases fall through: execution starts at MID and keeps going into HIGH because nothing stops it. Arrow cases never fall through.

Colon vs arrow

✗ Falls through
switch (level) {
    case LOW:  System.out.print("L");
    case MID:  System.out.print("M");
}

Forget one break and the next case runs too.

✓ Arrow cases
switch (level) {
    case LOW -> System.out.print("L");
    case MID -> System.out.print("M");
}

Each arrow runs only its own branch — no fall-through, no break needed.

💼 In the real world

Why seniors skip default

Payment code with switch expressions over all four PaymentStatus constants — and no default — is a gift to future you. When REFUNDED arrives, the build fails at every switch that forgot it, instead of refunds silently falling into some catch-all branch.

Key takeaways

  1. case RED -> ... uses the bare name (Color.RED is also allowed since Java 21)
  2. Switch expressions must cover every constant or have default
  3. Skipping default turns a new constant into a compile error — a feature
  4. Arrow cases never fall through; colon cases do without break
🤯 Did you know?

Before Java 21, case Color.RED: was a compile error — enum case labels had to be bare names. Java 21's pattern-matching switch finally allowed the qualified form.

Practice questions

What does this print?

enum Color { RED, GREEN, BLUE }
void main() {
    Color c = Color.GREEN;
    String hex = switch (c) {
        case RED -> "#f00";
        case GREEN -> "#0f0";
        case BLUE -> "#00f";
    };
    System.out.println(hex);
}
  1. #0f0
  2. #f00
  3. GREEN
  4. Compile error: missing default
Check your answer

#0f0. The GREEN case matches. All three constants are covered, so no default is needed.

What does this print?

enum Color { RED, GREEN, BLUE }
void main() {
    Color c = Color.RED;
    int n = switch (c) {
        case RED -> 1;
        case GREEN -> 2;
    };
    System.out.println(n);
}
  1. 1
  2. Compile error
  3. Throws MatchException
  4. 0
Check your answer

Compile error. Even though c is RED at runtime, the compiler checks every possible value: BLUE isn't covered, so the switch expression doesn't compile.

Next: a whole Set of weekdays that fits inside a single long — meet EnumSet and EnumMap.