Enum classes in Kotlin
In this chapter, we're going to introduce the concept of enum classes. Let's start with an example. Suppose that you’re implementing a payment method that has to support three possible options: cash payment, card payment, and bank transfer. The most basic way to represent a fixed set of values in Kotlin is an enum class. Inside its body, we list all the values, divided by a comma. We name values using UPPER_SNAKE_CASE notation (e.g., BANK_TRANSFER). Enum class elements can be referenced by the enum name, followed by a dot, and then the value name (e.g., PaymentOption.CASH). All values are typed as the enum class type.
Each enum class has the following companion object elements:
entriesproperty, which keeps a list of all the values of this enum class. It is a modern replacement of thevaluesfunction, that returns an array of elements3.valueOffunction, which parses a string into a value matching its name (this is case-sensitive) or throws an exception.
Instead of these methods, we can also use the top-level enumValues and enumValueOf functions.
As you can see, enum elements keep their values in order. This order is important. Each enum value has two properties:
name- the name of this value,ordinal- the position of this value (starting from 0).
Each enum class is a subclass of the abstract class Enum. This superclass guarantees the name and ordinal properties. Enum classes have properties that implement toString, equals, and hashCode, but, unlike data classes, they also have compareTo (their natural order is the order of the elements in the body).
Enum values can be used inside when-conditions. Moreover, there is no need to use the else-branch when all possible enum values are covered.
Enum classes are very convenient because they can be easily parsed or stringified. They are a popular way to represent a finite set of possible values.
Data in enum values
In Kotlin, each enum value can hold a state. It is possible to define a primary constructor for an enum class, and then each value needs to specify its data next to its name. It is the best practice that enum values should always be immutable, so their state should never change.
Enum classes with custom methods
Kotlin enums can have abstract methods whose implementations are item-specific. When we define them, the enum class itself needs to define an abstract method, and each item must override it:
This option is not popular as we generally prefer using functional primary constructor parameters1 or extension functions2.
Summary
Enum classes are a convenient way to represent a concrete set of possible values. Each value has the properties name and ordinal (position). We can get an array of all values using the values companion object function or the enumValues top-level function. We can also parse an enum value from String using the valueOf companion object function or the enumValueOf top-level function.
In the next chapter, we will talk about sealed classes, which are often treated as similar to enums but represent completely different and even more powerful abstractions. Sealed classes can form a closed hierarchy of classes, whereas enums represent only a set of constant values.
Functional variables are described in the book Functional Kotlin. An example of using an enum class with functional primary constructor parameters is presented in Effective Kotlin, Item 41: Use enum to represent a list of values.
Extension functions are described later in this book.
entries property was introduced in Kotlin 1.9, so in projects using older versions of Kotlin you need to use values instead.

