Enums in Java

Our enum type ServerState has an underlying int type.

public enum ServerState {
    STATE_IDLE,
    STATE_CONNECTED,
    STATE_ERROR,
    STATE_RETRYING
}

The possible values for ServerState are defined as constants.

By implementing the toString method, values of ServerState can be printed out or converted to strings.

import java.util.HashMap;
import java.util.Map;

public enum ServerState {
    STATE_IDLE,
    STATE_CONNECTED,
    STATE_ERROR,
    STATE_RETRYING;

    private static final Map<ServerState, String> stateName = new HashMap<>();
    
    static {
        stateName.put(STATE_IDLE, "idle");
        stateName.put(STATE_CONNECTED, "connected");
        stateName.put(STATE_ERROR, "error");
        stateName.put(STATE_RETRYING, "retrying");
    }

    @Override
    public String toString() {
        return stateName.get(this);
    }
}

If we have a value of type int, we cannot pass it to transition - the compiler will complain about type mismatch. This provides some degree of compile-time type safety for enums.

public class Main {
    public static void main(String[] args) {
        ServerState ns = transition(ServerState.STATE_IDLE);
        System.out.println(ns);

        ServerState ns2 = transition(ns);
        System.out.println(ns2);
    }

    public static ServerState transition(ServerState s) {
        switch (s) {
            case STATE_IDLE:
                return ServerState.STATE_CONNECTED;
            case STATE_CONNECTED:
            case STATE_RETRYING:
                // Suppose we check some predicates here to determine the next state…
                return ServerState.STATE_IDLE;
            case STATE_ERROR:
                return ServerState.STATE_ERROR;
            default:
                throw new IllegalArgumentException("Unknown state: " + s);
        }
    }
}

To run the program, compile the code and then run it using the java command.

$ javac Main.java
$ java Main
connected
idle

Next example: Struct Embedding.