Enums
Define a fixed set of named constants with enum, and add fields, methods, and abstract methods to make them powerful.
Overview
Key Points
- •enum Season { SPRING, SUMMER, AUTUMN, WINTER }
- •Enum constants are implicitly public static final instances of the enum type
- •values() returns all constants as an array; ordinal() gives the position (0-based)
- •name() returns the constant name as a String; valueOf("NAME") retrieves by name
- •Enums can have fields and a constructor called once per constant definition
- •Enums can have methods, including abstract methods overridden per constant
- •Enums implement interfaces
- •Use switch with enums for clean dispatch
Examples
Basic enum and switch
public class Main {
enum Direction { NORTH, SOUTH, EAST, WEST }
static String describe(Direction d) {
return switch (d) {
case NORTH -> "Go north";
case SOUTH -> "Go south";
case EAST -> "Go east";
case WEST -> "Go west";
};
}
public static void main(String[] args) {
Direction dir = Direction.NORTH;
System.out.println(dir); // NORTH
System.out.println(dir.ordinal()); // 0
System.out.println(dir.name()); // NORTH
System.out.println(describe(dir)); // Go north
for (Direction d : Direction.values()) {
System.out.println(d + " = " + d.ordinal());
}
}
}The switch expression with enum is exhaustive: the compiler knows all possible values, so no default is needed here.
Enum with fields and constructor
public class Main {
enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6);
private final double mass; // kg
private final double radius; // m
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
static final double G = 6.67300E-11;
double surfaceGravity() { return G * mass / (radius * radius); }
double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); }
}
public static void main(String[] args) {
double earthWeight = 75.0;
double mass = earthWeight / Planet.EARTH.surfaceGravity();
for (Planet p : Planet.values()) {
System.out.printf("Weight on %s: %.2f N%n", p, p.surfaceWeight(mass));
}
}
}Each enum constant calls the constructor with its own values. Fields can be accessed via methods, making enum constants full-featured objects.
Enum with abstract method
public class Main {
enum Operation {
PLUS("+") {
@Override public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
@Override public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
@Override public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
@Override public double apply(double x, double y) { return x / y; }
};
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
public abstract double apply(double x, double y);
@Override public String toString() { return symbol; }
}
public static void main(String[] args) {
double x = 10, y = 3;
for (Operation op : Operation.values()) {
System.out.printf("%.1f %s %.1f = %.2f%n", x, op, y, op.apply(x, y));
}
}
}Abstract methods in enums must be overridden by every constant. This is cleaner than a switch on the operation type.
Common Mistakes
- Comparing enum constants with equals instead of ==. Enums are singletons, so == is both correct and faster
- Expecting ordinal() to be stable across code changes. If you insert a constant in the middle, all following ordinals shift. Never persist ordinal values; use name() or a dedicated field instead
- Calling valueOf("invalid") which throws IllegalArgumentException. Wrap in try-catch or iterate values() if the input may not match
Note
EnumSet and EnumMap are specialised, highly efficient implementations for sets and maps whose elements or keys are enum constants. Prefer them over HashSet and HashMap when working with enums.
Exercises
Write Java code and click Run to execute it instantly. When your output looks correct, mark as done.
Completed: 0 / 4 exercises
Knowledge Check
Question 1 of 4