Enums in Groovy

Our enum type ServerState has an underlying int type.

The possible values for ServerState are defined as constants. The special keyword iota generates successive constant values automatically; in this case 0, 1, 2, and so on.

By implementing a mapping of ServerState to its name, values of ServerState can be printed out or converted to strings.

This can get cumbersome if there are many possible values. In such cases, tools can be used to automate the process.

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.

enum ServerState {
    StateIdle,
    StateConnected,
    StateError,
    StateRetrying;
    
    static def stateNames = [
        StateIdle: "idle",
        StateConnected: "connected",
        StateError: "error",
        StateRetrying: "retrying"
    ]

    @Override
    String toString() {
        return stateNames[this]
    }
}

def main() {
    def ns = transition(ServerState.StateIdle)
    println ns

    def ns2 = transition(ns)
    println ns2
}

def ServerState transition(ServerState s) {
    switch (s) {
        case StateIdle:
            return StateConnected
        case StateConnected, StateRetrying:
            // Suppose we check some predicates here to determine the next state…
            return StateIdle
        case StateError:
            return StateError
        default:
            throw new IllegalStateException("unknown state: $s")
    }
}

main()

To run the program, save the code in a file named EnumsExample.groovy and use the Groovy command-line tool to execute it:

$ groovy EnumsExample.groovy
connected
idle

Now that we can run and build basic Groovy programs, let’s learn more about the language.