Appearance
Lesson 04 · Enums
Objectives
After this lesson you will be able to:
- Declare enums with fields, constructors, and methods, and implement interfaces.
- Use
values(),valueOf(),ordinal(),name(), andcompareTo(). - Give constants per-constant behavior, and use enums in
switch. - Use
EnumSetandEnumMapfor enum-keyed collections.
Basics
An enum is a fixed set of named constant instances. Each constant is a singleton object of the enum type — implicitly public static final — so == and equals give the same answer.
java
enum Day { MON, TUE, WED }
Day d = Day.MON;
d.name(); // "MON"
d.ordinal(); // 0 (declaration position, zero-based)
Day.valueOf("TUE"); // Day.TUE — throws IllegalArgumentException if no match
Day.values(); // Day[] {MON, TUE, WED} — a fresh array each call
d == Day.MON; // true — single instance per constantExam trap
valueOf is case-sensitive and throws IllegalArgumentException (not NumberFormatException) for an unknown name. Avoid relying on ordinal() for logic or persistence — reordering constants silently changes the numbers. values() returns a new array each call (safe to mutate, but don't call it in a hot loop).
Fields, constructors, methods
An enum can have state and behavior. The constructor is implicitly private and runs once per constant, when the constant is created.
java
enum Planet {
EARTH(5.97e24, 6.37e6),
MARS(6.42e23, 3.39e6); // constants first, with constructor args
private final double mass, radius;
Planet(double mass, double radius) { // implicitly private
this.mass = mass; this.radius = radius;
}
double gravity() { return 6.67e-11 * mass / (radius * radius); }
}
Planet.EARTH.gravity();Gotcha
The constant list must come first in the body, ended with a semicolon before any fields/methods. An enum cannot be extended and cannot extend another class (it already extends java.lang.Enum), though it can implement interfaces. Its equals, hashCode, and compareTo are final — you can't override them.
Implementing interfaces
An enum can implement an interface — handy for plugging a fixed set of strategies into general code.
java
interface Labeled { String label(); }
enum Size implements Labeled {
SMALL, MEDIUM, LARGE;
public String label() { return name().toLowerCase(); } // shared by all constants
}
Size.MEDIUM.label(); // "medium"Comparison and built-in methods
Every enum extends java.lang.Enum, which supplies: name(), ordinal(), compareTo() (ordering by ordinal, i.e. declaration order), final equals/hashCode, plus the static values() and valueOf().
java
Size.SMALL.compareTo(Size.LARGE); // negative — ordinal 0 vs 2Per-constant bodies and switch
Each constant may override a method with a constant-specific class body (which compiles to an anonymous subclass of the enum):
java
enum Op {
PLUS { 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);
}
Op.PLUS.apply(2, 3); // 5Enums shine in switch, where you reference constants by simple name:
java
String label = switch (d) {
case MON, TUE, WED -> "weekday"; // not Day.MON — just MON
};Exam trap
In a switch on an enum, use the unqualified constant name (MON, not Day.MON) — qualifying it is a compile error. A switch expression over an enum must be exhaustive (cover every constant or add default). A null selector throws NullPointerException unless you handle it (a case null, or a null check first).
EnumSet and EnumMap
For collections keyed by an enum, the JDK provides compact, fast implementations: EnumSet (a bit-vector set of constants) and EnumMap (an array-backed map). Prefer them over HashSet/ HashMap for enum keys.
java
EnumSet<Size> big = EnumSet.of(Size.MEDIUM, Size.LARGE); // also allOf/noneOf/range
EnumMap<Size, Integer> stock = new EnumMap<>(Size.class);
stock.put(Size.SMALL, 10);SDET note
A fixed, type-safe constant set with behavior makes enums ideal for test data and state machines: exhaustive switch over an enum is compiler-checked, so adding a constant flags every place that must handle it.
Key Takeaways
- Each enum constant is a singleton instance (
public static final);==andequalsagree.name()is its identifier,ordinal()its 0-based position (don't depend on it). values()returns a fresh array;valueOfis case-sensitive and throwsIllegalArgumentExceptionon a miss.- Enums can have fields, methods, and a (private) constructor, implement interfaces, and give per-constant behavior — but cannot be extended.
equals/hashCode/compareToarefinal(compareToorders by ordinal). - In
switch, refer to constants by simple name; an enumswitchexpression must be exhaustive, and anullselector throws NPE unless handled. - Use
EnumSet/EnumMapfor enum-keyed collections.
Lesson Quiz
What does Day.valueOf("mon") do, given enum Day { MON, TUE }?
What is Day.WED.ordinal() given enum Day { MON, TUE, WED }?
An enum constructor is implicitly...
What is the sign of Size.SMALL.compareTo(Size.LARGE) given enum Size { SMALL, MEDIUM, LARGE }?
Which is TRUE about enums?
A switch EXPRESSION on an enum value omits some constants and has no default. What happens?
A switch on an enum receives a null reference and has no null handling. What happens?
Which collection is purpose-built for enum keys?
In a switch on a Day value, how do you reference the constant MON?
Next: Records. Run the matching code in labs/src/main/java/com/jse21/m03_oop/.