A switch expression computes a value. Arrow cases avoid statement fall-through, and a block case uses yield to supply its result.
Java switch expressions: return one value from every state
Operational contract
The enum has three states, and the switch handles each one without a default. Adding a new enum constant makes the source require another case when recompiled, rather than quietly classifying the new state as an old one. The HELD branch uses Math.addExact so an overflow does not produce a negative fee. Passing null still raises a NullPointerException before a case is selected; validate it at the call boundary when null is expected. A switch expression selects a branch; it does not make the arithmetic or state transition atomic with external storage.
Failure case
An order has a 2,300-cent base charge. READY keeps it; HELD adds a 47-cent hold fee and returns 2,347; CLOSED returns zero. A fourth state cannot be silently priced by a generic default branch in this source.
Java code
public class OrderChargeSwitch {
public enum State { READY, HELD, CLOSED }
public static long charge(State state, long baseCents) {
if (baseCents < 0) throw new IllegalArgumentException("Negative charge");
return switch (state) {
case READY -> baseCents;
case HELD -> {
long holdCharge = Math.addExact(baseCents, 47);
yield holdCharge;
}
case CLOSED -> 0;
};
}
}Performance and ownership cost
Branch selection and arithmetic take O(1) time and O(1) extra space. Exhaustive handling is a source-level maintenance property; it does not guarantee that an old compiled binary will understand a newer enum class without recompilation.
Common Mistakes
- Do not use break where a block case must yield a value.
- Do not hide a newly introduced enum state behind a permissive default.
- Do not forget overflow or null policy just because the switch is exhaustive.
Connected lessons
- Java conditions and loops
- Java enums: finite states without ordinal storage
- Java checked integer arithmetic: reject overflow before updating state
- Java interface defaults: resolve a two-parent method conflict
- Java compact record constructors: normalize before field assignment
- Java instanceof patterns: keep a narrowed value inside its valid scope
- Java sealed hierarchies: switch over permitted request kinds
- Java generics and language contracts quiz
- Advanced Java
