Enums

Java · Practical · 10 min

Enums replace magic strings and int codes with type-safe values the compiler can check.

An enum defines a type with a fixed set of named instances:

enum Status { PENDING, PAID, SHIPPED, CANCELLED }

Using Status instead of a String or int means typos fail at compile time, IDEs autocomplete the options, and method signatures document the allowed values.

Enums are full classes. Each constant can pass arguments to a constructor, and the enum can have fields and methods:

enum Planet {
    MERCURY(3.303e23), EARTH(5.976e24);
    private final double mass;
    Planet(double mass) { this.mass = mass; }
    double mass() { return mass; }
}

Every enum gets useful methods for free: values() returns all constants in declaration order, valueOf("PAID") converts from a string (throwing IllegalArgumentException for unknown names), name() and ordinal().

Enums are a natural fit for switch. A switch expression over an enum is exhaustive if it covers every constant, so you don't need default — and if someone later adds a constant, the compiler flags every switch that now misses it. That is a strong reason not to add a lazy default.

Constants are singletons, so comparing with == is correct and safe for enums.

Use EnumMap and EnumSet when keys or members are enum values; they are compact and very fast.

Don't persist ordinal() values to a database: reordering the constants silently changes their meaning. Store name() or an explicit code field instead.

Example

public class Orders {
    enum Status {
        PENDING("waiting for payment"), PAID("paid"), SHIPPED("on its way");

        private final String label;
        Status(String label) { this.label = label; }
        String label() { return label; }
    }

    static boolean canCancel(Status s) {
        return switch (s) {            // exhaustive: no default needed
            case PENDING, PAID -> true;
            case SHIPPED -> false;
        };
    }

    public static void main(String[] args) {
        for (Status s : Status.values()) {
            System.out.println(s + " (" + s.label() + ") cancel=" + canCancel(s));
        }
        Status parsed = Status.valueOf("PAID");
        System.out.println(parsed == Status.PAID);   // true
    }
}

Remember

  • Enums are type-safe, fixed sets of instances that can have fields and methods
  • Switch expressions over enums can be exhaustive without default
  • Comparing enum constants with == is correct

Watch out for

  • Storing ordinal() in a database; reordering constants then corrupts the data.

Check yourself

  1. A switch expression covers every constant of an enum and has no default. What happens when a new constant is added?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.oracle.com/javase/tutorial/java/javaOO/enum.html