An enum is a class with a fixed, named set of instances. It's type-safe, can carry fields and behaviour, and works in switch, EnumMap and EnumSet.
Built-in methods
public class Main {
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
public static void main(String[] args) {
Day d = Day.WED;
System.out.println(d + " " + d.name() + " " + d.ordinal());
System.out.println(Day.valueOf("FRI").compareTo(Day.MON)); // by ordinal
System.out.println(Day.values().length);
System.out.println(d == Day.WED); // safe: constants are singletons
try {
Day.valueOf("Funday");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}WED WED 2
4
7
true
No enum constant Main.Day.Funday| Member | Meaning |
|---|---|
values() | Array of all constants in declaration order (a fresh copy each call) |
valueOf(String) | Constant by exact name, else IllegalArgumentException |
name() / toString() | Declared name (toString can be overridden, name cannot) |
ordinal() | 0-based position — don't persist it; reordering constants changes it |
compareTo | Compares by ordinal; enums are Comparable |
Fields, constructors and methods
public class Main {
enum Planet {
MERCURY(3.303e+23, 2.4397e6),
EARTH(5.976e+24, 6.37814e6);
private final double mass, radius; // per-constant data
Planet(double mass, double radius) { // constructor is implicitly private
this.mass = mass;
this.radius = radius;
}
double surfaceGravity() {
return 6.67300E-11 * mass / (radius * radius);
}
}
public static void main(String[] args) {
for (Planet p : Planet.values())
System.out.printf("%s %.2f%n", p, p.surfaceGravity());
}
}MERCURY 3.70
EARTH 9.80Constant-specific bodies
public class Main {
enum Op {
ADD("+") { int apply(int a, int b) { return a + b; } },
MUL("*") { int apply(int a, int b) { return a * b; } };
final String symbol;
Op(String symbol) { this.symbol = symbol; }
abstract int apply(int a, int b); // each constant must implement it
}
public static void main(String[] args) {
for (Op op : Op.values())
System.out.println("6 " + op.symbol + " 7 = " + op.apply(6, 7));
}
}6 + 7 = 13
6 * 7 = 42Switch over an enum
public class Main {
enum Level { LOW, MEDIUM, HIGH }
static String action(Level l) {
return switch (l) { // exhaustive: no default needed
case LOW -> "ignore";
case MEDIUM -> "log";
case HIGH -> "page on-call";
};
}
public static void main(String[] args) {
for (Level l : Level.values()) System.out.println(l + " -> " + action(l));
}
}LOW -> ignore
MEDIUM -> log
HIGH -> page on-callEnumSet and EnumMap
import java.util.*;
public class Main {
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
public static void main(String[] args) {
EnumSet<Day> weekend = EnumSet.of(Day.SAT, Day.SUN); // a bit vector inside
EnumSet<Day> weekdays = EnumSet.complementOf(weekend);
System.out.println(weekdays);
System.out.println(EnumSet.range(Day.TUE, Day.THU));
Map<Day, Integer> hours = new EnumMap<>(Day.class); // array indexed by ordinal
hours.put(Day.FRI, 6);
hours.put(Day.MON, 8);
System.out.println(hours); // always in declaration order
}
}[MON, TUE, WED, THU, FRI]
[TUE, WED, THU]
{MON=8, FRI=6}The enum singleton
public class Main {
enum Registry {
INSTANCE;
private int count;
int next() { return ++count; }
}
public static void main(String[] args) {
Registry.INSTANCE.next();
System.out.println(Registry.INSTANCE.next());
}
}2Effective Java calls a single-element enum the best singleton: the JVM guarantees one instance, it is thread-safe to initialise, and it is safe against reflection and serialization attacks that break classic singletons.
Can an enum extend a class? Implement an interface?
Why is comparing enums with == safe?
Why can't an enum constructor be public?