Java › Enums
How would you use an EnumMap combined with a switch expression to implement a state machine, and what compile-time safety benefits does an exhaustive switch over an enum provide?
AdvancedAnswer
Modeling a state machine's states as an enum, with transitions defined either via an EnumMap<State, Map<Event, State>> lookup table or a switch expression over the current state and incoming event, gives you a structure the compiler can help verify is exhaustive (a switch expression over an enum, especially without a default branch in modern Java, forces you to explicitly handle every enum constant, immediately flagging at compile time if a new state is added but its transition handling was forgotten) -- this compile-time exhaustiveness checking is a meaningful safety benefit over an equivalent if/else chain or a Map-based lookup that would fail only at runtime (or silently do nothing) if a state was missed.
enum State { IDLE, RUNNING, PAUSED, STOPPED }
enum Event { START, PAUSE, RESUME, STOP }
State transition(State current, Event event) {
return switch (current) {
case IDLE -> event == Event.START ? State.RUNNING : current;
case RUNNING -> switch (event) {
case PAUSE -> State.PAUSED;
case STOP -> State.STOPPED;
default -> current;
};
case PAUSED -> event == Event.RESUME ? State.RUNNING : current;
case STOPPED -> current;
// Compiler ERROR if a new State constant is added but not handled here (no default case)
};
}Real-world example An order-processing state machine (PENDING, PAID, SHIPPED, DELIVERED, CANCELLED) implemented with an exhaustive switch expression immediately produces a compile error when a new CANCELLED_REFUNDED state is added to the enum but its transition logic is forgotten in the switch, catching an incomplete state machine implementation at build time rather than allowing a runtime bug to reach production.