# How to Declare and Use a Variable of an Enum Type in Kotlin: A Complete Guide

> Learn to declare and use Kotlin enum variables. Define enum classes assign constants to variables and access properties or use them in when expressions for robust code.

- Repository: [JetBrains/kotlin](https://github.com/jetbrains/kotlin)
- Tags: how-to-guide
- Published: 2026-02-16

---

**To declare and use a variable of an enum type in Kotlin, define an `enum class` with constants, then assign a specific constant to a variable typed with that enum class, allowing you to access properties like `name` and `ordinal` or use it in `when` expressions.**

Kotlin's enum implementation is defined in the `JetBrains/kotlin` repository, where every `enum class` automatically extends the platform-agnostic `Enum<E>` base class found in [`libraries/stdlib/src/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/Enum.kt). This design generates standard members like `values()` and `entries` while allowing the compiler to optimize enum usage across JVM, Native, JS, and WASM targets.

## Understanding Kotlin's Enum Implementation

### The Enum Base Class and Platform Abstraction

In [`libraries/stdlib/src/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/Enum.kt), Kotlin declares `Enum<E>` as an `expect` class. This means each platform (JVM, JavaScript, Native) provides its own `actual` implementation while maintaining a consistent API. For example, the Native implementation resides in [`kotlin-native/runtime/src/main/kotlin/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/kotlin-native/runtime/src/main/kotlin/kotlin/Enum.kt).

This abstraction allows the Kotlin compiler to treat enum types as sealed classes with a fixed set of instances, enabling exhaustive `when` checks and optimized memory layout on different platforms.

### Compiler-Generated Members for Enum Types

When you declare an `enum class`, the compiler automatically generates several members based on the definitions in [`libraries/stdlib/src/kotlin/enums/EnumEntries.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/enums/EnumEntries.kt) and related intrinsic functions:

- **`name: String`** — The exact identifier used in the source code
- **`ordinal: Int`** — Zero-based position of the constant in the declaration
- **`values(): Array<E>`** — Returns a new array containing all constants (allocates fresh array on each call)
- **`valueOf(name: String): E`** — Looks up a constant by name, throwing `IllegalArgumentException` if not found
- **`entries: EnumEntries<E>`** — An immutable list view introduced in Kotlin 1.9 that avoids allocation on repeated access

The JVM-specific implementation of these generators can be found in [`compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt`](https://github.com/JetBrains/kotlin/blob/main/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt), which handles the IR lowering that emits platform-specific bytecode for `values()` and `entries`.

## How to Declare an Enum Class in Kotlin

To declare an enum type, use the `enum class` keyword followed by the constant definitions. You can include properties, methods, and even implement interfaces. The following example is adapted from the test suite at [`plugins/kapt/kapt-compiler/testData/converter/enums.kt`](https://github.com/JetBrains/kotlin/blob/main/plugins/kapt/kapt-compiler/testData/converter/enums.kt):

```kotlin
enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF);

    // Instance method available on any Color variable
    fun hex() = "#%06X".format(rgb)
}

```

Each enum entry is a singleton object of type `Color`. The compiler generates a final class `Color` that extends `Enum<Color>`, making `RED`, `GREEN`, and `BLUE` the only possible instances of this type.

## How to Declare and Use a Variable of an Enum Type

### Mutable and Immutable Enum Variables

Once you have defined an `enum class`, you can declare variables using the enum type as you would any other class. The type system ensures that only valid enum constants can be assigned:

```kotlin
// Mutable variable that can be reassigned
var current: Color = Color.RED

// Immutable reference that cannot change
val favorite = Color.BLUE

```

The explicit type annotation `: Color` on the `var` declaration is optional when the initializer is present, but including it improves readability and IDE navigation. Because `Color` extends `Enum<Color>`, these variables have access to all standard enum properties.

### Accessing Enum Properties and Methods

Variables of enum type expose the compiler-generated properties and any custom methods defined in the enum class:

```kotlin
println(current.name)       // "RED"
println(current.ordinal)    // 0
println(current.hex())      // "#FF0000" - custom method

// Safe comparison using == (enums are singletons)
if (current == Color.RED) {
    println("Currently red")
}

```

The `name` and `ordinal` properties are declared in the base `Enum<E>` class, while `hex()` is specific to the `Color` example. Because enum entries are singleton objects, reference equality (`===`) and structural equality (`==`) yield the same result.

## Iterating Over Enum Constants: values() vs entries

When you need to enumerate all constants of an enum type, Kotlin provides two main approaches with different performance characteristics.

### Using values()

The `values()` function returns a new `Array<E>` containing all enum constants:

```kotlin
val allColors: Array<Color> = Color.values()
println(allColors.contentToString()) // [RED, GREEN, BLUE]

```

**Important:** `values()` creates a fresh array on every invocation. In performance-critical code or tight loops, this allocation overhead can accumulate.

### Using entries (Recommended)

Introduced in Kotlin 1.9 and defined in [`libraries/stdlib/src/kotlin/enums/EnumEntries.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/enums/EnumEntries.kt), the `entries` property returns an `EnumEntries<E>` — an immutable list view that avoids allocation:

```kotlin
for (c in Color.entries) {
    println("${c.ordinal}: ${c.name}")
}

```

The `EnumEntries` interface extends `List<E>` and provides constant-time `contains` and `indexOf` operations. For generic code, you can use the `enumEntries<T>()` inline function, which returns the same cached list without requiring a specific enum class reference.

**When to use which:**
- Use **`entries`** for read-only iteration, membership checks, or when exposing enum constants as a collection
- Use **`values()`** only when you specifically need a mutable `Array` instance

## Using Enum Types in Functions and Data Classes

Enum types integrate seamlessly with Kotlin's type system, making them ideal for function parameters and data class properties. The compiler can verify exhaustive `when` expressions when using enum variables:

```kotlin
data class Pixel(val color: Color, val x: Int, val y: Int)

fun draw(pixel: Pixel) {
    when (pixel.color) {
        Color.RED   -> println("Drawing red pixel at (${pixel.x}, ${pixel.y})")
        Color.GREEN -> println("Drawing green pixel")
        Color.BLUE  -> println("Drawing blue pixel")
    }
}

```

Because `Color` is a sealed type with a fixed set of instances, the compiler knows that the `when` expression is exhaustive. If you add a new color constant later, the compiler will flag any incomplete `when` blocks as errors, preventing runtime bugs.

## Key Implementation Files in the Kotlin Repository

The enum functionality described above is implemented across several key files in the `JetBrains/kotlin` repository:

| File | Role |
|------|------|
| [`libraries/stdlib/src/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/Enum.kt) | Defines the abstract `Enum<E>` base class as an `expect` class |
| [`libraries/stdlib/src/kotlin/enums/EnumEntries.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/enums/EnumEntries.kt) | Declares `EnumEntries<E>` interface and `enumEntries()` intrinsic function |
| [`plugins/kapt/kapt-compiler/testData/converter/enums.kt`](https://github.com/JetBrains/kotlin/blob/main/plugins/kapt/kapt-compiler/testData/converter/enums.kt) | Test data showing concrete enum declarations with properties and methods |
| [`compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt`](https://github.com/JetBrains/kotlin/blob/main/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/EnumClassLowering.kt) | JVM-specific IR lowering that generates `values()` and `entries` implementations |
| [`kotlin-native/runtime/src/main/kotlin/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/kotlin-native/runtime/src/main/kotlin/kotlin/Enum.kt) | Native platform `actual` implementation of the `Enum` base class |

These files demonstrate how Kotlin abstracts enum behavior through `expect`/`actual` declarations while allowing platform-specific optimizations in the compiler backend.

## Summary

- **Enum declaration**: Use `enum class` to create a type with a fixed set of named constants, optionally including properties and methods as shown in [`plugins/kapt/kapt-compiler/testData/converter/enums.kt`](https://github.com/JetBrains/kotlin/blob/main/plugins/kapt/kapt-compiler/testData/converter/enums.kt).
- **Variable declaration**: Declare variables using the enum type (e.g., `var current: Color = Color.RED`) to leverage Kotlin's type-safe singleton semantics.
- **Standard properties**: Access `name` and `ordinal` from the base `Enum<E>` class defined in [`libraries/stdlib/src/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/Enum.kt).
- **Efficient iteration**: Prefer `entries` (returning `EnumEntries<E>` from [`libraries/stdlib/src/kotlin/enums/EnumEntries.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/enums/EnumEntries.kt)) over `values()` to avoid array allocations in performance-critical code.
- **Exhaustive checks**: Use enum variables in `when` expressions to enable compiler-verified exhaustive pattern matching.

## Frequently Asked Questions

### How do I declare a variable that can hold any enum constant in Kotlin?

Declare the variable using the enum class name as the type, followed by the specific constant assignment. For example: `var status: Status = Status.ACTIVE`. The type system ensures that only constants defined in that enum class can be assigned to the variable, preventing invalid states at compile time.

### What is the difference between values() and entries in Kotlin enums?

The `values()` function returns a new `Array` containing all enum constants on every invocation, which allocates memory each time. The `entries` property, introduced in Kotlin 1.9, returns an immutable `EnumEntries` list that caches the constants, avoiding allocation on repeated access. Use `entries` for iteration and membership checks, and `values()` only when you specifically need a mutable array instance.

### Can I add custom properties and methods to a Kotlin enum?

Yes, enum classes in Kotlin can contain constructors, properties, and methods just like regular classes. Each enum constant can pass arguments to the constructor, as shown in the `Color` example from [`plugins/kapt/kapt-compiler/testData/converter/enums.kt`](https://github.com/JetBrains/kotlin/blob/main/plugins/kapt/kapt-compiler/testData/converter/enums.kt) where `RED(0xFF0000)` passes an RGB value. You can also define abstract methods in the enum class and implement them individually for each constant.

### How does Kotlin ensure type safety with enum variables?

Kotlin treats each enum class as a sealed type with a fixed set of singleton instances defined at compile time. The compiler generates a final class extending `Enum<E>` (defined in [`libraries/stdlib/src/kotlin/Enum.kt`](https://github.com/JetBrains/kotlin/blob/main/libraries/stdlib/src/kotlin/Enum.kt)), ensuring that variables of that type can only reference the predefined constants. This enables exhaustive `when` expressions and prevents null or invalid states without runtime checks.