skip to content

Enum Classes

Kotlin enums are classes, so constants can carry state, override behavior individually, and implement interfaces. Interviewers use them to check you know more than the constant list, including the modern entries property.

part ofKotlinoverview, primer and where to startread it →
on this pageshow

explore

questions

20

How do you declare an enum class in Kotlin, and what is an enum constant?

level: juniorimportance: must knowfreq 80%

answer

  1. enum class Name { A, B, C }
  2. each constant = singleton instance
  3. enum is a soft modifier on class
  4. extends kotlin.Enum, can't pick superclass
  5. exhaustive when, no else needed

basics

~10 s

Write enum class Name { A, B, C }. Each capitalized name inside the braces (A, B, C) is a constant — a fixed, named instance of that enum that you reference as Name.A.

solid answer

~40 s

An enum class declares a fixed set of named instances. You write `enum class Color { RED, GREEN, BLUE }`; RED, GREEN, BLUE are the enum constants — each is a singleton object of type Color. The keyword pair is `enum class` (enum is a soft modifier on class). Constants are listed first in the body, comma-separated. You reference them by qualified name (`Color.RED`) and they can be used in exhaustive `when` expressions. Each constant is created exactly once at class load. Enums implicitly extend `kotlin.Enum`, so they inherit `name`, `ordinal`, `compareTo`, `equals`/`hashCode`, and a synthetic `valueOf`/`entries`. If the body has only constants, the trailing semicolon after the list is optional.

code

kotlin · 4 lines
kotlin
enum class Direction { NORTH, EAST, SOUTH, WEST }

val d: Direction = Direction.NORTH
println(d == Direction.NORTH) // true, same singleton

go deeper

for a junior

Can write the basic enum class { A, B, C } syntax and reference a constant.

for a middle

Knows constants are singletons, the soft-modifier syntax, and when the trailing semicolon is required.

for a senior

Explains the kotlin.Enum supertype, exhaustive when, and the inability to choose a superclass.

for a principal

Discusses tradeoffs of enums vs sealed classes for closed sets and the implications for binary/API evolution.

## What an enum class is An **enum class** is a class whose set of instances is **fixed and known at compile time**. You declare it with the keyword pair `enum class`. Each named value you list is an **enum constant** — a single, pre-created instance of the class. ```kotlin enum class Direction { NORTH, EAST, SOUTH, WEST } ``` Here `Direction` is the type and `NORTH`, `EAST`, `SOUTH`, `WEST` are its four constants. Each is a **singleton**: `Direction.NORTH` always refers to the very same object, created once when the class is loaded. ## Key facts - **Syntax**: `enum` is a *soft modifier* applied to `class`. You cannot write just `enum Foo` — it must be `enum class Foo`. - **Listing constants**: constants come **first** in the class body, comma-separated. If the enum has *nothing else* in the body, the trailing semicolon is optional. If you add members (properties/functions) after the constants, you must terminate the constant list with a `;`. - **Type**: every constant has the enum type. `Direction.NORTH` is a `Direction`. - **Inheritance**: every Kotlin enum implicitly extends the abstract class `kotlin.Enum<E>`. You **cannot** specify a superclass (enums already have one), but they *can* implement interfaces (a sibling topic). - **Usage in `when`**: because the instance set is closed, a `when` over an enum can be **exhaustive** — if you cover every constant, no `else` branch is required. ```kotlin fun describe(d: Direction): String = when (d) { Direction.NORTH -> "up" Direction.EAST -> "right" Direction.SOUTH -> "down" Direction.WEST -> "left" } ``` ## Referencing constants You use the qualified name `Direction.NORTH`. Inside a `when` you can import them or rely on smart context. Constants compare with `==` (identity-safe because they are singletons) and also work with `===`. ## What you get for free Because of the `kotlin.Enum` supertype, each constant automatically has a `name` (its declared identifier as a String) and an `ordinal` (its zero-based position), plus the companion-like `valueOf(name)` and `entries` accessors. Those are covered in detail in other questions.

  • Can an enum class extend another class?
    No. Every enum implicitly extends kotlin.Enum, so you cannot declare a superclass. It can, however, implement one or more interfaces.
  • When is the semicolon after the constant list required?
    Only when the body contains members (properties/functions) after the constants. With constants alone the trailing semicolon is optional.

Like the compass points or days of the week — a small, closed, named set that never grows at runtime.

saying these in an interview costs you the question

  • Writing `enum Foo` without the `class` keyword
  • Thinking each constant is a new instance every time it's referenced
  • Claiming enums can extend an arbitrary base class
  • Saying a when over an enum always needs an else branch
  • Confusing enum constants with companion-object members

context

open as a page

In Kotlin, how do you make each enum constant run its own different code for the same operation? Show a small example.

level: juniorimportance: must knowfreq 55%

basics

~10 s

Declare an abstract function in the enum, then give each constant a body in curly braces that overrides it. Calling the function on a constant runs that constant's version.

open as a page

What is the `entries` property on a Kotlin enum class, and how does it differ from the older `values()` function?

level: juniorimportance: must knowfreq 70%

basics

~10 s

entries gives you all the constants of an enum as a read-only list. The old values() did the same but returned an array, and it made a brand-new copy every time you called it.

open as a page

How does a Kotlin enum class implement an interface, and how can the implementation differ per enum constant?

level: juniorimportance: must knowfreq 55%

basics

~10 s

Put the interface name after a colon in the enum header. You can implement the interface once for all constants, or let each constant override the method with its own version inside its body.

open as a page

How do you give each enum constant constructor parameters, and how are those values supplied per constant?

level: middleimportance: must knowfreq 70%

basics

~10 s

Add a constructor to the enum class, then put the argument values in parentheses after each constant, like RED(0xFF0000). Each constant supplies its own values, and you read them as normal properties.

open as a page

What do the built-in `name` and `ordinal` properties of an enum constant return, and what should you be careful about with `ordinal`?

level: middleimportance: must knowfreq 65%

basics

~10 s

name gives the constant's declared identifier as a String (e.g. "RED"). ordinal gives its zero-based position in the declaration list (0, 1, 2...). Be careful: reordering constants changes every ordinal.

open as a page

Can a constant that has its own override body also pass constructor arguments? Show how per-constant bodies combine with a primary constructor and shared state.

level: middleimportance: should knowfreq 30%

basics

~10 s

Yes. Put the constructor arguments in parentheses after the constant name, then the override body in braces. Each constant can carry shared data and still have its own behavior.

open as a page

Explain exactly what the Kotlin compiler generates for an enum that has per-constant anonymous-class bodies, and why a semicolon after the constant list is mandatory.

level: middleimportance: should knowfreq 35%

basics

~10 s

Each constant with its own body becomes a separate hidden subclass of the enum. The semicolon is needed to mark where the constant list ends and member declarations begin.

open as a page

Explain the performance/allocation difference between iterating `MyEnum.values()` and `MyEnum.entries`, and when it actually matters.

level: middleimportance: should knowfreq 55%

basics

~10 s

values() builds a new array every time you call it, which creates garbage. entries reuses one shared list, so it allocates nothing. It matters in hot loops or tight memory situations.

open as a page

What do the top-level `enumValues<T>()`, `enumValueOf<T>()`, and `enumEntries<T>()` functions do, and why must `T` be `reified`?

level: middleimportance: should knowfreq 45%

basics

~20 s

They let generic code get an enum's constants without naming the specific enum. enumValues gives all constants, enumValueOf finds one by name, enumEntries gives the cached list. They need reified so the real type is known at runtime.

open as a page

Explain how abstract members and per-constant bodies interact when an enum implements an interface. What does the compiler generate, and how does dispatch work?

level: middleimportance: should knowfreq 35%

basics

~20 s

If the enum leaves an interface method abstract, every constant must give it a body. The compiler makes each such constant its own hidden subclass, so calling the method picks the right constant's version automatically.

open as a page

Show how a Kotlin enum can implement multiple interfaces while providing a class-level default that only some constants override. What are the constraints?

level: middleimportance: should knowfreq 40%

basics

~10 s

List the interfaces comma-separated after the colon. Implement one as a class-level default that all constants inherit, and override it only in the constants that need different behavior.

open as a page

Why can enum constants be compared safely with `==`, and what does it mean that each constant is a singleton?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Each enum constant exists as exactly one object created once at class load. So referencing RED always gives the same instance, and == (which compares value) and === (which compares identity) both reliably tell constants apart.

open as a page

What does `valueOf()` do for an enum, and how does it behave when given an unknown name?

level: seniorimportance: should knowfreq 55%

basics

~10 s

valueOf("RED") looks up an enum constant by its exact name and returns it. If no constant has that name, it throws an IllegalArgumentException instead of returning null.

open as a page

When would you prefer per-constant enum bodies over a sealed class hierarchy, and how do per-constant abstract property overrides work?

level: seniorimportance: should knowfreq 28%

basics

~20 s

Use per-constant enum bodies for a fixed, small set of singletons that share one operation. Use sealed classes when variants carry different data shapes or need multiple instances. Property overrides use an abstract val with a per-constant getter.

open as a page

When migrating a codebase from `values()` to `entries`, what concrete behavioral and API differences could break or surprise you?

level: seniorimportance: should knowfreq 35%

basics

~20 s

entries is a List, not an Array, so array-only operations and code that mutated the result will break. The shared instance also means you must never try to modify it. Order and contents stay the same.

open as a page

When would you model behavior with an enum implementing an interface versus a sealed interface/class hierarchy? What trade-offs drive the choice?

level: seniorimportance: should knowfreq 30%

basics

~10 s

Use an enum-implementing-interface when you have a small fixed list of stateless named values that each carry behavior. Use a sealed hierarchy when variants need their own data fields or many instances.

open as a page

A teammate has a bodied enum where each constant overrides apply(). They want to add a brand-new operation that depends on each constant. Compare extending the enum with a new abstract method vs handling it in an external when, and discuss the dispatch and maintainability tradeoffs.

level: seniorimportance: nice to knowfreq 18%

basics

~10 s

Adding a new abstract method forces every constant to implement it (compile-safe, behavior stays with the constant). An external when keeps the enum closed but risks forgetting a constant unless the when is exhaustive.

open as a page

What is the `EnumEntries<E>` type, what guarantees does it provide, and how does the compiler back the `entries` property?

level: seniorimportance: nice to knowfreq 22%

basics

~10 s

EnumEntries<E> is a special read-only list type that holds all of an enum's constants. The compiler generates the entries property to return one shared, unchangeable instance for the enum.

open as a page

An enum implements an interface and you must dispatch/lookup constants by a runtime value while keeping the interface clean. How do you design this idiomatically in Kotlin?

level: seniorimportance: nice to knowfreq 18%

basics

~20 s

Keep the per-value behavior in each constant via the interface, and add a companion object with a lookup function (built from entries) to find the right constant from a runtime key. Callers use the interface, not the enum.

open as a page