ZetCode

Java Enum Class

Last modified: April 13, 2025

The java.lang.Enum class serves as the common base for all Java enumeration types. Enums provide a way to define a set of named constants, ensuring type safety and improving code readability and maintainability. They eliminate the need for traditional constant definitions using static final variables, preventing invalid values from being assigned.

Like regular classes, enums in Java can contain fields, methods, and constructors, but they are primarily used to represent fixed sets of constants with built-in type safety. They can implement interfaces, allowing additional behavior customization, but cannot extend other classes since they implicitly extend java.lang.Enum. This makes enums the ideal choice for representing fixed sets of related constants, such as days of the week, error codes, or configuration options.

Enum Class Methods

The Enum class provides several utility methods that help manage and interact with enum instances. Some key methods include:

By leveraging enums, developers can create structured, self-documenting code while ensuring correctness through enforced value constraints.

Basic Enum Declaration

The simplest form of enum declaration defines a set of named constants. Each constant is an instance of the enum type. Enums are implicitly public, static, and final. They can be used in switch statements and provide compile-time type safety.

Main.java
enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
    THURSDAY, FRIDAY, SATURDAY
}

void main() {

    Day today = Day.WEDNESDAY;
    
    System.out.println("Today is: " + today);
    System.out.println("Ordinal value: " + today.ordinal());
    System.out.println("Name: " + today.name());
    
    // Using enum in switch statement
    switch (today) {
        case MONDAY:
            System.out.println("Start of work week");
            break;
        case WEDNESDAY:
            System.out.println("Midweek");
            break;
        case FRIDAY:
            System.out.println("Almost weekend");
            break;
        default:
            System.out.println("Other day");
    }
}

This example demonstrates a basic enum declaration and usage. The Day enum defines seven constants representing days of the week. We show how to access an enum constant, its ordinal value, and name. The example also demonstrates using enums in switch statements.

Enum with Fields and Methods

Enums can have fields, methods, and constructors just like regular classes. Each enum constant can have its own instance-specific behavior. The enum constructor must be private or package-private as enum constants can only be created within the enum itself.

Main.java
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),
    JUPITER(1.9e+27, 7.1492e7),
    SATURN(5.688e+26, 6.0268e7),
    URANUS(8.686e+25, 2.5559e7),
    NEPTUNE(1.024e+26, 2.4746e7);
    
    private final double mass;   // in kilograms
    private final double radius; // in meters
    
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    
    public double surfaceGravity() {
        double G = 6.67300E-11;
        return G * mass / (radius * radius);
    }
    
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

void main() {

    double earthWeight = 70; // kg
    double mass = earthWeight / Planet.EARTH.surfaceGravity();
    
    for (Planet p : Planet.values()) {
        System.out.printf("Your weight on %s is %f kg%n",
                         p, p.surfaceWeight(mass));
    }
}

This example shows an enum with fields and methods. The Planet enum represents planets in our solar system with mass and radius properties. Each planet constant provides methods to calculate surface gravity and weight. The example calculates and prints a person's weight on each planet.

Enum with Abstract Methods

Enums can declare abstract methods that must be implemented by each enum constant. This allows each constant to define its own behavior while sharing common enum functionality. This pattern is known as the constant-specific method implementation.

Main.java
enum Operation {

    PLUS {
        public double apply(double x, double y) { return x + y; }
    },
    MINUS {
        public double apply(double x, double y) { return x - y; }
    },
    TIMES {
        public double apply(double x, double y) { return x * y; }
    },
    DIVIDE {
        public double apply(double x, double y) { return x / y; }
    };
    
    public abstract double apply(double x, double y);
}

void main() {

    double x = 10;
    double y = 5;
    
    for (Operation op : Operation.values()) {
        System.out.printf("%s %s %s = %s%n",
                        x, op, y, op.apply(x, y));
    }
}

This example demonstrates an enum with an abstract method. The Operation enum defines four basic arithmetic operations. Each constant implements the apply method with its specific behavior. The example shows how to iterate through all operations and apply them to sample values.

Enum Implementing Interfaces

Enums can implement interfaces just like regular classes. This allows enums to provide polymorphic behavior while maintaining their type safety and fixed set of instances. Each enum constant can implement interface methods differently.

Main.java
interface Command {
    void execute();
}

enum FileOperation implements Command {
    OPEN {
        public void execute() {
            System.out.println("Opening file...");
        }
    },
    SAVE {
        public void execute() {
            System.out.println("Saving file...");
        }
    },
    CLOSE {
        public void execute() {
            System.out.println("Closing file...");
        }
    };
}

void main() {

    Command[] operations = FileOperation.values();
    
    for (Command cmd : operations) {
        cmd.execute();
    }
}

This example shows an enum implementing an interface. The FileOperation enum implements the Command interface, with each constant providing its own implementation of the execute method. The example demonstrates how to treat enum constants polymorphically through the interface.

Enum with Static Factory Method

Enums can have static factory methods that return enum constants based on specific criteria. This is useful when you need to look up enum constants by properties other than their name. The valueOf method provided by default only looks up by name.

Main.java
enum HttpStatus {

    OK(200, "OK"),
    NOT_FOUND(404, "Not Found"),
    SERVER_ERROR(500, "Internal Server Error");
    
    private final int code;
    private final String description;
    
    HttpStatus(int code, String description) {
        this.code = code;
        this.description = description;
    }
    
    public int getCode() { return code; }
    public String getDescription() { return description; }
    
    public static HttpStatus fromCode(int code) {
        for (HttpStatus status : values()) {
            if (status.code == code) {
                return status;
            }
        }
        throw new IllegalArgumentException("No status for code: " + code);
    }
}

void main() {

    HttpStatus status = HttpStatus.fromCode(404);
    System.out.println(status + ": " + status.getDescription());
    
    try {
        HttpStatus.fromCode(999);
    } catch (IllegalArgumentException e) {
        System.out.println("Error: " + e.getMessage());
    }
}

This example demonstrates an enum with a static factory method. The HttpStatus enum represents HTTP status codes with their descriptions. The fromCode method looks up statuses by their numeric code. The example shows both successful lookup and error handling.

Enum with State and Behavior

Enums can maintain state and implement complex behavior. They can be used to implement state machines or other patterns where a fixed set of instances with specific behavior is needed. This example shows a simple vending machine state.

Main.java
enum VendingMachineState {

    IDLE {
        public VendingMachineState nextState() {
            return WAITING_FOR_MONEY;
        }
    },
    WAITING_FOR_MONEY {
        public VendingMachineState nextState() {
            return DISPENSING;
        }
    },
    DISPENSING {
        public VendingMachineState nextState() {
            return IDLE;
        }
    },
    OUT_OF_STOCK {
        public VendingMachineState nextState() {
            return this;
        }
    };
    
    public abstract VendingMachineState nextState();
}

void main() {

    VendingMachineState state = VendingMachineState.IDLE;
    
    System.out.println("Initial state: " + state);
    
    state = state.nextState();
    System.out.println("After first transition: " + state);
    
    state = state.nextState();
    System.out.println("After second transition: " + state);
    
    state = state.nextState();
    System.out.println("After third transition: " + state);
    
    state = VendingMachineState.OUT_OF_STOCK;
    System.out.println("Out of stock state remains: " + 
                      state.nextState());
}

This example shows an enum implementing a simple state machine. The VendingMachineState enum represents different states of a vending machine. Each state knows its next state through the nextState method. The example demonstrates state transitions and the special case of OUT_OF_STOCK which doesn't transition.

Source

Java Enum Class Documentation

In this article, we've covered all major aspects of the Java Enum class with practical examples. Enums are powerful constructs that go beyond simple constants, offering type safety, encapsulation, and polymorphic behavior.

Author

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.