Enums
Type-safe constants with fields, constructors, methods, switch, values(), EnumMap and EnumSet.
Some variables can only ever hold one of a small, fixed set of values: the days of the week, the status of an order, the suit of a playing card. Beginners often use int or String constants for these:
An enum (enumerated type) defines a type whose only possible values are the constants you list. The compiler rejects anything else, your IDE autocompletes the options, and you get a set of useful methods for free.
Declaring and using an enum#
Every enum automatically gets:
Each constant is a single object created once by the JVM, so compare enums with ==. Constants are written in UPPER_SNAKE_CASE by convention.
Enums in switch#
Enums and switch fit together perfectly. Inside the cases you write the bare constant name. With a modern switch expression (Java 14+), the compiler checks that you covered every constant, so no default is needed:
If you later add a constant like HOLIDAY, every exhaustive switch expression that doesn't handle it becomes a compile error, which points you at every place that needs updating. That is a great safety net.
Fields, constructors and methods#
Enums are full classes. Each constant can carry data, passed to a constructor:
Rules:
- The constants must come first, followed by a
;if anything else follows. - Enum constructors are always
private; you can never callnew Planet(...). - Fields should be
final. Enum constants are shared globally, so mutable state in them behaves like a global variable.
A practical example: order status with codes
Storing a stable code (or name()) in a database is much safer than storing ordinal(), which changes if you ever reorder the constants.
Constant-specific behaviour#
Each constant can have its own body that overrides a method. Combined with an abstract method, the compiler forces every constant to implement it:
Enums can also implement interfaces (enum Op implements IntBinaryOperator), but they cannot extend a class, because every enum already extends java.lang.Enum.
EnumSet and EnumMap#
The java.util package has collections tuned specially for enums. Internally they use bit flags and arrays indexed by ordinal, so they are faster and more compact than HashSet/HashMap, and they keep the constants in declaration order:
EnumSet is the modern replacement for "bit flag" int constants: EnumSet.of(Permission.READ, Permission.WRITE) reads far better than READ | WRITE.
Enums as singletons#
Because the JVM guarantees each constant exists exactly once, a one-constant enum is the simplest thread-safe singleton:
Common mistakes#
- Using
intorStringconstants where an enum would make invalid values impossible. - Passing user input straight to
valueOfwithout handlingIllegalArgumentException(or without normalising case, for exampleDay.valueOf(input.strip().toUpperCase())). - Persisting
ordinal()values. - Writing
case Day.MONDAY:in older Java versions; in aswitchon an enum, plaincase MONDAYis the normal style (qualified names are only allowed from Java 21). - Forgetting the
;after the last constant when the enum has fields or methods. - Putting mutable fields in enum constants.
What's next#
Our programs now have many classes. The next lesson, packages, imports and JARs, shows you how to organise them into folders and namespaces and ship them as a single file.
Check your understanding
Quick quiz
1.What does
Size.valueOf("huge")do ifSizehas constantsSMALL, MEDIUM, LARGE?2.Which is the safest way to compare two enum values?
3.Why is relying on
ordinal()to store an enum in a database a bad idea?
Finished reading?
Mark this lesson complete to track your progress.