Enums
An enum (enumeration) is a type with a fixed set of named values: the days of the week, order statuses, card suits. Using an enum instead of strings or numbers makes invalid values impossible and lets the compiler check your switches. Java enums are full classes, so they can also carry data and behaviour.
A basic enum
enum Status { PENDING, SHIPPED, DELIVERED, CANCELLED } public class Main { public static void main(String[] args) { Status s = Status.SHIPPED; System.out.println(s); System.out.println(s == Status.SHIPPED); System.out.println(s.name() + " is number " + s.ordinal()); System.out.println(Status.valueOf("DELIVERED")); for (Status each : Status.values()) { System.out.print(each + " "); } System.out.println(); } }
SHIPPED true SHIPPED is number 1 DELIVERED PENDING SHIPPED DELIVERED CANCELLED
Enum constants are conventionally in capitals. Compare them with == (each constant is a single object). values() lists them all, and valueOf converts text to a constant — throwing IllegalArgumentException for unknown names.
Why not strings?
With String status, nothing stops "shiped" or "Delivered " slipping in. With Status status, only the four valid values exist — typos become compile errors, and IDEs can autocomplete.
Enums in switch
enum Status { PENDING, SHIPPED, DELIVERED, CANCELLED } public class Main { static String message(Status s) { return switch (s) { case PENDING -> "We're preparing your order."; case SHIPPED -> "Your order is on its way."; case DELIVERED -> "Delivered. Enjoy!"; case CANCELLED -> "This order was cancelled."; }; } public static void main(String[] args) { System.out.println(message(Status.PENDING)); } }
We're preparing your order.
A switch expression over an enum needs no default when every constant is covered. If you later add a constant, the compiler flags every switch that doesn't handle it.
Fields, constructors and methods
enum Size { SMALL("S", 250), MEDIUM("M", 350), LARGE("L", 500); private final String code; private final int millilitres; Size(String code, int millilitres) { this.code = code; this.millilitres = millilitres; } String code() { return code; } double priceFrom(double basePerLitre) { return basePerLitre * millilitres / 1000; } } public class Main { public static void main(String[] args) { for (Size s : Size.values()) { System.out.println("%s (%s): %.2f".formatted(s, s.code(), s.priceFrom(8.0))); } } }
SMALL (S): 2.00 MEDIUM (M): 2.80 LARGE (L): 4.00
Each constant can pass values to a (private) constructor, and the enum can have fields and methods like any class.
Behaviour per constant
enum Operation { ADD("+") { int apply(int a, int b) { return a + b; } }, SUBTRACT("-") { int apply(int a, int b) { return a - b; } }, MULTIPLY("*") { int apply(int a, int b) { return a * b; } }; final String symbol; Operation(String symbol) { this.symbol = symbol; } abstract int apply(int a, int b); } public class Main { public static void main(String[] args) { for (Operation op : Operation.values()) { System.out.println("6 " + op.symbol + " 3 = " + op.apply(6, 3)); } } }
6 + 3 = 9 6 - 3 = 3 6 * 3 = 18
EnumMap and EnumSet
import java.util.EnumMap; import java.util.EnumSet; import java.util.Map; enum Day { MON, TUE, WED, THU, FRI, SAT, SUN } public class Main { public static void main(String[] args) { EnumSet<Day> weekend = EnumSet.of(Day.SAT, Day.SUN); EnumSet<Day> workdays = EnumSet.complementOf(weekend); System.out.println(workdays); Map<Day, Integer> hours = new EnumMap<>(Day.class); hours.put(Day.MON, 8); hours.put(Day.FRI, 6); System.out.println(hours); } }
[MON, TUE, WED, THU, FRI]
{MON=8, FRI=6}Specialised collections for enum keys are compact and fast, and keep the declaration order.
Try it yourself
Model a traffic light that knows its next state and how long it lasts.
t=0s RED t=30s GREEN t=55s YELLOW t=60s RED