Enum Basics
Enum Basics
Before enums arrived in Java 5, developers represented a fixed set of related constants using public static final int fields — the so-called int enum pattern. It worked, but it was fragile: nothing stopped you from passing an arbitrary integer where only a specific set of values made sense, and the values had no type safety whatsoever.
The enum keyword solves all of that. An enum declares a named type whose legal values are a fixed set of constants you enumerate up-front. The compiler then enforces that only those values can ever inhabit a variable of that type.
Declaring an Enum
The syntax looks like a class declaration, but uses the enum keyword:
Each identifier in the body — MONDAY, TUESDAY, and so on — is a constant of type Day. By convention, enum constants are written in UPPER_SNAKE_CASE, exactly like other constants in Java.
enum Day compiles into a class that extends java.lang.Enum<Day>. Each constant is a public static final Day field of that class. This means enums can have constructors, fields, and methods — topics covered in later lessons.
Using Enum Constants
You reference a constant with the type name and a dot, just like a static field:
name() returns the constant name as a String. ordinal() returns its zero-based position in the declaration order. Both are inherited from the base class java.lang.Enum.
Iterating All Constants
Every enum automatically gets a static values() method that returns an array of all constants in declaration order:
There is also a static valueOf(String name) method that does the reverse lookup:
valueOf throws IllegalArgumentException if the string does not match any constant name exactly (case-sensitive).
Enums in switch
One of the most natural uses of an enum is as the selector in a switch statement. Because the compiler knows every possible value of the enum, it can warn you if you forget a case, and the code reads very clearly:
Notice that inside the case labels you write only the constant name — MONDAY, not Day.MONDAY. The compiler already knows the type from the switch selector.
Java 14+ introduced switch expressions, which are cleaner and force you to cover every case (or provide a default):
The arrow form (->) eliminates fall-through and the need for break. When every constant is covered and there is no default, the compiler enforces exhaustiveness — if you add a new constant to the enum later, the switch expression will refuse to compile until you handle the new case. That is a powerful safety guarantee.
Equality and Comparison
Because each constant is a singleton — exactly one object exists for each constant — you can safely compare enum values with == instead of .equals():
Enum constants are also Comparable (their natural order is declaration order), and they are Serializable by default.
Summary
Enums replace fragile constant patterns with a type-safe named set. The core ideas to remember: declare with enum, reference constants as Type.CONSTANT, iterate with values(), convert from string with valueOf(), use in switch for readable branching (and prefer the switch-expression form for exhaustiveness), and compare with ==. The next lesson extends enums with custom fields and methods.