Java Enum — Type-Safe Constants with Fields, Methods & More

3 minute read

An enum (short for enumeration) is a special Java type used to define a fixed set of constants. Unlike plain static final fields, enums are type-safe, can have fields and methods, and work beautifully with switch.


Why Enums?

Before Enums (The Problem)

// BAD — magic numbers
public static final int STATUS_PENDING  = 0;
public static final int STATUS_APPROVED = 1;
public static final int STATUS_REJECTED = 2;

void process(int status) { ... }   // any int is accepted!
process(42);  // compiles but makes no sense

With Enums (The Solution)

public enum Status {
    PENDING, APPROVED, REJECTED
}

void process(Status status) { ... }
process(Status.APPROVED);  // ✅ type-safe
process(42);               // ❌ compile error

Declaring Enums

public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
    FRIDAY, SATURDAY, SUNDAY
}

Each constant is a public static final instance of the enum.

Day today = Day.FRIDAY;
System.out.println(today);        // FRIDAY
System.out.println(today.name()); // FRIDAY
System.out.println(today.ordinal()); // 4 (zero-based position)

Enums in switch

Day day = Day.SATURDAY;

switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY ->
        System.out.println("Weekday");
    case SATURDAY, SUNDAY ->
        System.out.println("Weekend!");
}

In switch, you write MONDAY, not Day.MONDAY.


values() and valueOf()

// Iterate all constants
for (Day d : Day.values()) {
    System.out.println(d);
}

// Convert from String
Day monday = Day.valueOf("MONDAY");  // MONDAY
Day bad    = Day.valueOf("FUNDAY");  // IllegalArgumentException

Enums with Fields, Constructors, and Methods

public 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;  // metres

    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }

    public double getMass()   { return mass; }
    public double getRadius() { return radius; }

    // Surface gravity: G * mass / radius²
    public double surfaceGravity() {
        return 6.67300E-11 * mass / (radius * radius);
    }

    // Weight on this planet
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}
double earthWeight = 75.0;
double mass = earthWeight / Planet.EARTH.surfaceGravity();

for (Planet p : Planet.values()) {
    System.out.printf("Weight on %s: %.2f%n", p, p.surfaceWeight(mass));
}

Important: Enum constructors are always private (you can omit the keyword).


Enum Implementing Interfaces

public interface Describable {
    String describe();
}

public enum Season implements Describable {
    SPRING { public String describe() { return "Flowers bloom"; } },
    SUMMER { public String describe() { return "Sun shines"; } },
    AUTUMN { public String describe() { return "Leaves fall"; } },
    WINTER { public String describe() { return "Snow falls"; } };
}

Or with a shared implementation:

public enum Priority implements Comparable<Priority> {
    LOW(1), MEDIUM(5), HIGH(10);

    private final int level;
    Priority(int level) { this.level = level; }
    public int getLevel() { return level; }
}

Abstract Methods in Enums

public enum Operation {
    ADD {
        public double apply(double a, double b) { return a + b; }
    },
    SUBTRACT {
        public double apply(double a, double b) { return a - b; }
    },
    MULTIPLY {
        public double apply(double a, double b) { return a * b; }
    },
    DIVIDE {
        public double apply(double a, double b) { return a / b; }
    };

    public abstract double apply(double a, double b);
}

// Usage
double result = Operation.ADD.apply(3, 4);  // 7.0

EnumSet — High-Performance Set for Enums

import java.util.EnumSet;

EnumSet<Day> weekend  = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
EnumSet<Day> weekdays = EnumSet.complementOf(weekend);
EnumSet<Day> all      = EnumSet.allOf(Day.class);
EnumSet<Day> none     = EnumSet.noneOf(Day.class);

weekend.contains(Day.SUNDAY)  // true

Internally implemented as a bit vector — extremely fast and memory-efficient.


EnumMap — Map Keyed by Enum

import java.util.EnumMap;

EnumMap<Day, String> schedule = new EnumMap<>(Day.class);
schedule.put(Day.MONDAY, "Gym");
schedule.put(Day.FRIDAY, "Movie night");

System.out.println(schedule.get(Day.MONDAY));  // "Gym"

More efficient than HashMap when keys are enums.


Singleton Pattern with Enum

The simplest and safest way to implement a singleton in Java:

public enum Database {
    INSTANCE;

    private final Connection connection;

    Database() {
        connection = createConnection();
    }

    public Connection getConnection() {
        return connection;
    }

    private Connection createConnection() {
        // ... create and return connection
        return null;
    }
}

// Usage
Database.INSTANCE.getConnection();

This is thread-safe, serialisation-safe, and reflection-proof — something other singleton patterns cannot guarantee.


Common Mistakes

Mistake Problem Fix
Comparing enums with .equals() Works but unnecessary Use == (enums are singletons)
Using ordinal() for logic Breaks when order changes Use fields instead
Mutable fields in enums Shared state, thread issues Make fields final
Using valueOf() without try-catch IllegalArgumentException on bad input Validate or catch
// GOOD — safe valueOf
public static Optional<Day> fromString(String name) {
    try {
        return Optional.of(Day.valueOf(name.toUpperCase()));
    } catch (IllegalArgumentException e) {
        return Optional.empty();
    }
}

Key Takeaways

  1. Enums provide type-safe constants — far better than int or String constants.
  2. Enums can have fields, constructors, and methods.
  3. Use EnumSet and EnumMap for high-performance enum collections.
  4. Compare enums with ==, not .equals().
  5. Enum is the best singleton pattern in Java.

What’s Next?

Next: Java Math Class — Math.abs(), Math.random(), Math.pow(), and the Random class.

Updated: