Java Enums

Represent a fixed set of values such as sizes, statuses or directions with enums, and give them fields, constructors and methods.

Lesson 60 of 127Intermediate17 min read

Plenty of values in programs come from a short, fixed list. A T-shirt is small, medium or large. An order is pending, paid, shipped or delivered. A traffic light is red, amber or green. You could store them as strings like "SHIPPED" or numbers like 2, but then nothing stops a typo such as "SHIPED" or a meaningless 7 slipping in, and the compiler can't help you.

An enum (short for enumeration) defines a type whose only possible values are the ones you list. OrderStatus.SHIPPED can't be misspelled, a method that takes an OrderStatus can't receive anything else, and your editor can autocomplete the options.

Java's enums are more powerful than in many languages: each constant is a real object that can carry data and have methods. In this lesson you'll declare enums, use them in conditions and switch expressions, loop over their values, attach fields and behaviour, and use the special EnumMap and EnumSet collections.

Declaring and using an enum

Java
enum Size { SMALL, MEDIUM, LARGE }

Size mine = Size.MEDIUM;
if (mine == Size.MEDIUM) {
    System.out.println("Medium it is");
}
  • The constants are written in CAPITALS by convention, separated by commas.
  • Use them as TypeName.CONSTANT.
  • Compare enum values with ==. Each constant exists exactly once, so == is safe and fast.
  • An enum can sit in its own file, like a class, or inside another class.

Built-in methods

Every enum automatically gets these methods:

MethodReturnsExample
values()An array of all constants, in orderSize.values()
valueOf("LARGE")The constant with that nameSize.LARGE
name()The constant's name as a String"LARGE"
ordinal()Its position, starting at 02

valueOf throws an IllegalArgumentException if the text doesn't match exactly, including capitals, so handle that when converting user input. Avoid storing ordinal() in files or databases: reordering the constants later would change every number.

Enums and switch

Enums and switch are a perfect pair. Inside the switch, write the constants without the type name:

Java
String label = switch (status) {
    case PENDING -> "Waiting for payment";
    case PAID, SHIPPED -> "On its way";
    case DELIVERED -> "Arrived";
};

When a switch expression covers every constant, no default is needed. Better still, if someone later adds a new constant such as RETURNED, the compiler reports every switch expression that doesn't handle it, so nothing is forgotten.

Fields, constructors and methods

Constants can carry data. Add fields, a constructor and methods after the list, which then ends with a semicolon:

Java
enum Planet {
    MERCURY(3.7), EARTH(9.8), MARS(3.7);

    private final double gravity;

    Planet(double gravity) { this.gravity = gravity; }

    double weightOf(double massKg) { return massKg * gravity; }
}

The value in brackets after each constant is passed to the constructor. An enum's constructor is always private: you can't create new constants with new. Java also offers EnumMap and EnumSet, very fast maps and sets designed for enum keys.

Different behaviour for each constant

An enum can declare an abstract method and give each constant its own body, so the behaviour lives right next to the constant instead of in a switch elsewhere:

Java
enum Operation {
    ADD {
        int apply(int a, int b) { return a + b; }
    },
    MULTIPLY {
        int apply(int a, int b) { return a * b; }
    };

    abstract int apply(int a, int b);
}

Operation.MULTIPLY.apply(3, 4) returns 12. A new constant can't be added without its own apply body, because the compiler insists on it. Enums can also implement interfaces, which is useful when an enum needs to fit an existing contract such as Comparator or your own Describable. For simple data, the field-and-constructor style above stays shorter; reach for constant-specific bodies when the logic genuinely differs. More advanced patterns are in the enum constructors lesson.

Java Enums Syntax

Enum syntax

enum Name { A, B, C }

enum Name {
    A(1), B(2);
    private final int value;
    Name(int value) { this.value = value; }
    int value() { return value; }
}

Name.values()   Name.valueOf("A")   x.name()   x.ordinal()
Map<Name, Integer> m = new EnumMap<>(Name.class);

Java Enums Summary

  • An enum defines a type with a fixed set of named constants.
  • Compare enum values with ==; use them directly in switch cases.
  • values(), valueOf(), name() and ordinal() are available on every enum.
  • Enums can have fields, a constructor and methods; each constant passes its own data.
  • EnumMap and EnumSet are efficient collections for enum keys and values.

Java Enums Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Order statuses with switch

Java
public class Main {
    enum Status { PENDING, PAID, SHIPPED, DELIVERED }

    static String describe(Status s) {
        return switch (s) {
            case PENDING -> "Waiting for payment";
            case PAID -> "Packing your order";
            case SHIPPED -> "On its way";
            case DELIVERED -> "Delivered";
        };
    }

    public static void main(String[] args) {
        for (Status s : Status.values()) {
            System.out.println(s.ordinal() + " " + s + ": " + describe(s));
        }
        Status fromText = Status.valueOf("SHIPPED");
        System.out.println(fromText == Status.SHIPPED);
    }
}
Output
0 PENDING: Waiting for payment
1 PAID: Packing your order
2 SHIPPED: On its way
3 DELIVERED: Delivered
true
Line-by-line explanation
  1. Line 2Four possible statuses, and nothing else is allowed.
  2. Lines 5 to 10Every constant is covered, so the switch expression needs no default.
  3. Line 13values() loops through the constants in the order they were declared.
  4. Line 16valueOf turns text into the matching constant.
Example 2

An enum with data and behaviour

Java
public class Main {
    enum Coffee {
        ESPRESSO("Espresso", 2.20),
        LATTE("Latte", 3.10),
        FLAT_WHITE("Flat white", 3.30);

        private final String label;
        private final double price;

        Coffee(String label, double price) {
            this.label = label;
            this.price = price;
        }

        double priceFor(int cups) {
            return price * cups;
        }

        String label() { return label; }
    }

    public static void main(String[] args) {
        for (Coffee c : Coffee.values()) {
            System.out.printf("%-11s £%.2f, three for £%.2f%n",
                    c.label(), c.price, c.priceFor(3));
        }
    }
}
Output
Espresso    £2.20, three for £6.60
Latte       £3.10, three for £9.30
Flat white  £3.30, three for £9.90
Line-by-line explanation
  1. Lines 3 to 5Each constant passes a label and a price to the constructor.
  2. Lines 10 to 13The constructor stores them in final fields.
  3. Lines 15 to 17A method that every constant can use with its own price.
  4. Lines 24 to 25The main method is in the same class, so it can read the private field directly.
Example 3

Counting with an EnumMap

Java
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

public class Main {
    enum Size { SMALL, MEDIUM, LARGE }

    public static void main(String[] args) {
        List<Size> orders = List.of(Size.LARGE, Size.SMALL, Size.LARGE,
                                    Size.MEDIUM, Size.LARGE);
        Map<Size, Integer> counts = new EnumMap<>(Size.class);
        for (Size s : orders) {
            counts.merge(s, 1, Integer::sum);
        }
        System.out.println(counts);
    }
}
Output
{SMALL=1, MEDIUM=1, LARGE=3}
Line-by-line explanation
  1. Line 11An EnumMap needs to know which enum it holds.
  2. Line 13merge adds 1 to the existing count, or starts at 1.
  3. Line 15An EnumMap always lists keys in the enum's declared order, not the order they were added.

Common Java Enums Mistakes

Using strings for fixed options

Don't
String size = "MEDUIM";                 // typo compiles fine
Do
Size size = Size.MEDIUM;                // a typo won't compile

valueOf with the wrong case

Don't
Size s = Size.valueOf("large");         // IllegalArgumentException
Do
Size s = Size.valueOf("large".toUpperCase());

Wrap it in try and catch when the text comes from a user.

Saving ordinal() values

Don't
saveToFile(status.ordinal());           // 2 means SHIPPED... until the list changes
Do
saveToFile(status.name());              // "SHIPPED" stays meaningful

Java Enums in Real Projects

Enums in real code

Java's own libraries use enums widely: DayOfWeek.MONDAY and Month.MARCH in the date-time API, and TimeUnit.SECONDS for timeouts. Applications use enums for user roles, payment methods, order states and game states, often with a switch expression that the compiler checks for completeness.

Java Enums FAQ

Should I compare enums with == or equals()?

Use ==. Each enum constant exists exactly once, so == is correct, slightly faster and safe when the left side is null, where status.equals(...) would throw. equals() also works, but it's not needed.

How do I convert a string to an enum safely?

Size.valueOf("LARGE") works only for an exact match and throws IllegalArgumentException otherwise. For user input, normalise it first, Size.valueOf(text.trim().toUpperCase()), inside a try/catch, or loop over Size.values() and compare names with equalsIgnoreCase to return a default when nothing matches.

Can an enum extend a class?

No. Every enum automatically extends java.lang.Enum, and Java allows only one parent class. An enum can implement any number of interfaces, which covers most needs.

How should enums be stored in a database or file?

Store the constant's name(), such as "SHIPPED", or a code held in a field you control. Avoid ordinal(), because inserting or reordering constants silently changes every stored number. Read values back with valueOf or a lookup method that handles unknown codes.

Are enum constants singletons?

Yes. Java creates each constant once, when the enum class is loaded, and that loading is thread-safe. This is why a single-constant enum is a recognised way to write a singleton in Java.

Java Enums Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the declaration of an enum for a traffic light.

 Light { RED, AMBER, GREEN }
Multiple choiceeasy

How should two enum values be compared?

Predict the outputmedium

What does this print?

enum Size { SMALL, MEDIUM, LARGE }
System.out.println(Size.LARGE.ordinal());
Multiple choicemedium

What does Size.values() return?

Multiple choicehard

Why doesn't a switch expression over every enum constant need a default?

Java Enums Quiz

5 questions to check what you learned.

  1. What is an enum?

    • A list that can grow
    • A type with a fixed set of named constants
    • A kind of loop
    • A number format
  2. Can an enum have fields and methods?

    • No
    • Only static methods
    • Yes, plus a constructor called once per constant
    • Only in Java 21
  3. What happens with Size.valueOf("HUGE") if HUGE isn't a constant?

    • It returns null
    • It returns SMALL
    • It creates HUGE
    • It throws IllegalArgumentException
  4. Inside switch (size), how do you write the case for Size.SMALL?

    • case SMALL ->
    • case Size.SMALL ->
    • case "SMALL" ->
    • case 0 ->
  5. Why avoid storing ordinal() values permanently?

    • They're too large
    • They're private
    • They change every time the program runs
    • Reordering or inserting constants changes the numbers, breaking saved data