Java Enums
Define a fixed set of constants in Java with enum types, including enums with fields, constructors, and methods.
An enum is a class whose instances are a fixed, known-at-compile-time set of values. Days of the week, traffic-light colors, order statuses — anything where the legal values are a small, named list. Once you write enum Status { OPEN, CLOSED }, those two are the only Status values that will ever exist, and the compiler will tell you if you try to invent a third.
Enums replace the old C habit of public static final int OPEN = 0;. Integer constants give you no type safety — setStatus(7) compiles — but setStatus(Status status) only accepts one of the declared values.
Declaring an enum
The simplest form is just a list of constant names:
public enum Direction {
NORTH, EAST, SOUTH, WEST
}Use it like any other type:
Direction d = Direction.NORTH;
if (d == Direction.NORTH) System.out.println("heading up");Each constant is a singleton instance of Direction. Comparing with == is correct and idiomatic — there's only ever one NORTH in the JVM, so reference equality matches value equality.
In a switch
Enums and switch are made for each other:
switch (d) {
case NORTH -> System.out.println("up");
case SOUTH -> System.out.println("down");
case EAST, WEST -> System.out.println("sideways");
}Notice the bare NORTH instead of Direction.NORTH — inside a switch on an enum, the compiler knows the type. If you add a new constant and forget to handle it in a switch expression, you'll get a compile error about non-exhaustiveness, which is exactly the safety net you want.
Fields, constructors, and methods
An enum can carry data and behavior. Each constant is constructed with arguments, and the enum body can define normal methods:
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6);
private final double massKg;
private final double radiusM;
Planet(double massKg, double radiusM) {
this.massKg = massKg;
this.radiusM = radiusM;
}
public double surfaceGravity() {
final double G = 6.67300E-11;
return G * massKg / (radiusM * radiusM);
}
}Two rules to remember:
- The constant list comes first in the body, separated from the rest by a semicolon.
- The constructor is implicitly private — enums can't be instantiated from outside, which is the whole point.
Built-in methods
Every enum gets a few methods for free:
name()returns the constant's declared name as aString.ordinal()returns its zero-based position in the declaration. Useful occasionally; avoid persisting it because reordering constants silently changes the meaning.values()returns an array of all constants in declaration order — great forfor (Direction d : Direction.values())loops.valueOf(String)looks up a constant by name and throwsIllegalArgumentExceptionif there's no match.
Per-constant behavior
Sometimes one constant needs to behave differently from the others. You can override methods per constant with an anonymous body:
public enum Operation {
PLUS { public int apply(int a, int b) { return a + b; } },
MINUS { public int apply(int a, int b) { return a - b; } },
TIMES { public int apply(int a, int b) { return a * b; } };
public abstract int apply(int a, int b);
}Each constant becomes a tiny anonymous subclass of Operation that implements apply. The strategy-pattern feel comes for free.
Implementing interfaces
Enums can implement interfaces — they just can't extend other classes (they implicitly extend java.lang.Enum):
public enum Day implements Runnable {
MONDAY, TUESDAY;
public void run() { System.out.println("today is " + name()); }
}This is a clean way to plug a fixed family of strategies into code that wants any Runnable.
EnumSet and EnumMap
When you need a Set or Map keyed by an enum, prefer EnumSet and EnumMap — both backed by bit-vectors or arrays sized to the enum, so they're tiny and fast:
EnumSet<Direction> horizontal = EnumSet.of(Direction.EAST, Direction.WEST);
EnumMap<Direction, String> labels = new EnumMap<>(Direction.class);
labels.put(Direction.NORTH, "up");A worked example
What's next
Enums lock down a fixed set of instances. The next chapter introduces a different shape of restricted class — records, designed for plain immutable data carriers. Continue to Java records.
Practice
What is the main reason to use an enum instead of a set of int constants?