Enums
Type-safe fixed sets of values — enums as full-fledged objects with state and behavior
Lots of values in our programs come from small, fixed sets: days
of the week, traffic-light colors, payment methods, user roles,
HTTP methods. You could represent each by an int or a String,
and at first that even feels natural — but you would be throwing
away type safety and inviting a class of avoidable bugs.
Java's enum is the right tool. It is a class whose instances
are defined once, in the class itself, and cannot be created
anywhere else. That makes enums one of the most pleasant features
in Java to use.
The problem enums solve
The String version compiles fine even for nonsense values. The
compiler cannot help you. Let's see the same idea with an enum.
Three concrete benefits in that small change:
- Type safety.
respond(Light)cannot be called with an arbitrary string. The compiler enforces that you pass a realLight. - Exhaustiveness aid. When you add
FLASHINGtoLight, the compiler can warn you (in IDEs) that theswitchno longer handles every case. - Self-documenting.
Light.REDis impossible to misread.
Enums are objects too
Java enums are not just integer codes with names. Each enum constant is a full object, and the enum type is a class. That means each constant can carry its own state and define its own behavior.
A few things to notice:
- The constants
MERCURY, VENUS, EARTH, MARSare listed first, followed by a semicolon, then the rest of the class body. - Enums have private final fields and a constructor, just like ordinary classes. You cannot call the constructor yourself — Java calls it once for each declared constant.
- Methods like
surfaceGravity()work like any other instance method. Each enum constant gets to compute its own answer.
Enums with per-constant behavior
For more variation, each enum constant can override methods to behave differently. This is the closest thing in Java to "an interface implemented by a fixed list of objects."
Each enum constant is implementing the abstract apply method in
its own way. The set of operations is fixed; the behavior of each
is encapsulated with the constant. This is a clean, very-OOP
alternative to a giant switch over a String operator.
Common useful methods that enums get for free
| Method | What it does |
|---|---|
values() | Returns an array of all constants, in declaration order |
valueOf(String) | Returns the constant with the given name (throws if missing) |
name() | Returns the constant's name as a String |
ordinal() | Returns the constant's position (0-based) — useful, but use sparingly |
A small modeling example: payment methods
Even a slightly more interesting business concept fits beautifully in an enum:
Practice
Define an enum Day with values MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY and an instance method isWeekend() returning true only for SATURDAY and SUNDAY.
The provided Main prints each day along with whether it is a weekend. Expected output:
MONDAY weekend? false
TUESDAY weekend? false
WEDNESDAY weekend? false
THURSDAY weekend? false
FRIDAY weekend? false
SATURDAY weekend? true
SUNDAY weekend? true
Test your understanding
Which is the strongest reason to prefer an enum over a String for a fixed set of values like traffic-light colors?
Enums use less memory than strings
The compiler can guarantee at compile time that only valid values are passed; typos and made-up values are rejected
Strings cannot be switch-ed on
Enums automatically log their values to disk
Which of these is true about Java enums?
Each enum constant is just an integer with a label
You can create new enum instances with new at runtime
Enums cannot have fields or methods
Each enum constant is an object, and the enum type may have its own fields, constructor, and methods
What does Operation.values() return?
A single random constant
A Set of constants
An array containing every declared constant, in the order they were declared
The number of constants in the enum