Bird
Raised Fist0
Kotlinprogramming~15 mins

Enum class declaration in Kotlin - Deep Dive

Choose your learning style10 modes available
Overview - Enum class declaration
What is it?
An enum class in Kotlin is a special type that lets you define a group of named constants. Each constant is an object of the enum class. This helps you represent a fixed set of related values, like days of the week or directions, in a clear and safe way.
Why it matters
Without enum classes, programmers might use plain numbers or strings to represent fixed sets of values, which can cause mistakes and confusion. Enum classes make code easier to read, safer to use, and help prevent errors by restricting values to a known set.
Where it fits
Before learning enum classes, you should understand basic Kotlin classes and objects. After mastering enums, you can explore sealed classes and advanced Kotlin features like data classes and generics.
Mental Model
Core Idea
An enum class is like a labeled box of fixed, named options where each option is a unique object you can use safely in your code.
Think of it like...
Imagine a box of colored pencils where each pencil has a fixed color name. You can only pick from these pencils, never invent a new color on the spot.
EnumClass Example:
┌───────────────┐
│ EnumClass     │
│ ┌───────────┐ │
│ │ CONSTANT1 │ │
│ │ CONSTANT2 │ │
│ │ CONSTANT3 │ │
│ └───────────┘ │
└───────────────┘
Each CONSTANT is a unique object inside the EnumClass.
Build-Up - 6 Steps
1
FoundationBasic Enum Class Declaration
🤔
Concept: How to declare a simple enum class with named constants.
In Kotlin, you declare an enum class using the keyword 'enum class' followed by the name and a list of constants separated by commas inside curly braces. Example: enum class Direction { NORTH, SOUTH, EAST, WEST }
Result
You get a new type 'Direction' with four fixed values: NORTH, SOUTH, EAST, and WEST.
Understanding the syntax of enum classes is the first step to using fixed sets of values safely in your programs.
2
FoundationUsing Enum Constants in Code
🤔
Concept: How to use enum constants as values and compare them.
You can assign enum constants to variables and compare them using '==' or 'when' expressions. Example: val dir = Direction.NORTH if (dir == Direction.SOUTH) { println("Going south") } else { println("Not south") }
Result
The program prints 'Not south' because dir is NORTH. This shows enum constants behave like unique objects you can compare.
Knowing enum constants are singleton objects lets you use simple equality checks without errors.
3
IntermediateAdding Properties and Methods
🤔
Concept: Enum constants can have properties and functions to hold extra data or behavior.
You can define properties and methods inside an enum class. Each constant can pass values to the constructor. Example: enum class Direction(val degrees: Int) { NORTH(0), EAST(90), SOUTH(180), WEST(270); fun description() = "Direction is $degrees degrees" } Usage: println(Direction.EAST.description())
Result
Output: Direction is 90 degrees Each enum constant holds its own data and behavior.
Enums are more than fixed names; they can carry data and functions, making them powerful for modeling real-world concepts.
4
IntermediateUsing 'when' with Enum Classes
🤔Before reading on: do you think 'when' expressions require an 'else' branch when covering all enum constants? Commit to your answer.
Concept: How Kotlin's 'when' expression works with enum classes and exhaustiveness checking.
When you use 'when' with all enum constants covered, Kotlin knows it's exhaustive and you don't need an 'else'. Example: when(dir) { Direction.NORTH -> println("Up") Direction.SOUTH -> println("Down") Direction.EAST -> println("Right") Direction.WEST -> println("Left") } If you miss one constant, Kotlin will ask for an 'else' branch.
Result
The program prints the direction name without needing an 'else' if all cases are handled.
Kotlin's exhaustiveness check with enums helps catch missing cases at compile time, preventing bugs.
5
AdvancedEnum Classes Implementing Interfaces
🤔Before reading on: can enum constants have different behavior by overriding interface methods? Commit to your answer.
Concept: Enum classes can implement interfaces, and each constant can override methods differently.
You can define an interface and have enum constants provide their own implementation. Example: interface Action { fun execute(): String } enum class Operation : Action { ADD { override fun execute() = "Adding" }, SUBTRACT { override fun execute() = "Subtracting" } } println(Operation.ADD.execute())
Result
Output: Adding Each enum constant can behave uniquely by overriding methods.
Enums can model complex behavior variations cleanly, making them useful beyond simple constants.
6
ExpertEnum Class Internals and Memory Model
🤔Before reading on: do you think enum constants are created each time you use them or only once? Commit to your answer.
Concept: How Kotlin creates enum constants as singleton objects loaded once at runtime.
Enum constants are created once when the enum class is loaded. They are singletons, meaning the same object is reused everywhere. This saves memory and ensures identity checks with '==' work reliably. Behind the scenes, Kotlin generates a static array holding all constants and provides 'values()' and 'valueOf()' methods.
Result
Enum constants behave like fixed, unique objects with guaranteed identity and efficient memory use.
Knowing enum constants are singletons explains why identity checks are safe and why enums are efficient for fixed sets.
Under the Hood
When Kotlin compiles an enum class, it creates a final class extending java.lang.Enum. Each enum constant is a static final instance of this class, created once at class load time. The compiler also generates a static array holding all constants for iteration and lookup. Methods like 'values()' return a copy of this array, and 'valueOf()' finds a constant by name. Enum constants are singleton objects, so identity checks with '==' compare references safely. This design ensures enums are memory-efficient and type-safe fixed sets.
Why designed this way?
Enums were designed to replace error-prone integer or string constants with a type-safe, readable alternative. Using singleton objects for constants ensures identity and memory efficiency. The static array and generated methods provide convenient iteration and lookup. This design balances performance, safety, and usability, avoiding the pitfalls of loose constants while fitting well with Java and Kotlin's object model.
Enum Class Structure:

┌─────────────────────────────┐
│ EnumClass extends java.lang.Enum │
│                             │
│  ┌───────────────┐          │
│  │ CONSTANT1     │◄───────┐ │
│  ├───────────────┤       │ │
│  │ CONSTANT2     │◄───────┼─┤
│  ├───────────────┤       │ │
│  │ CONSTANT3     │◄───────┘ │
│  └───────────────┘          │
│                             │
│  static final EnumClass[]   │
│  valuesArray                │
│                             │
│  values() returns copy of   │
│  valuesArray                │
│                             │
│  valueOf(name) searches     │
│  valuesArray                │
└─────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do enum constants in Kotlin behave like integers internally? Commit to yes or no.
Common Belief:Enum constants are just integer values behind the scenes.
Tap to reveal reality
Reality:Enum constants are actually singleton objects, not integers. They have identity and can hold properties and methods.
Why it matters:Treating enums as integers can lead to bugs when comparing or extending them, and misses the power of enums as objects.
Quick: Can you add new constants to an enum class at runtime? Commit to yes or no.
Common Belief:You can add new enum constants dynamically while the program runs.
Tap to reveal reality
Reality:Enum constants are fixed at compile time and cannot be changed or added at runtime.
Why it matters:Trying to modify enums dynamically breaks the fixed-set guarantee and can cause runtime errors or unexpected behavior.
Quick: Does Kotlin require an 'else' branch in 'when' expressions covering all enum constants? Commit to yes or no.
Common Belief:You always need an 'else' branch in 'when' expressions, even if all enum constants are covered.
Tap to reveal reality
Reality:If all enum constants are covered, Kotlin treats the 'when' as exhaustive and does not require an 'else'.
Why it matters:Knowing this helps write cleaner code and avoid unnecessary branches.
Quick: Are enum constants recreated each time you access them? Commit to yes or no.
Common Belief:Each time you use an enum constant, a new object is created.
Tap to reveal reality
Reality:Enum constants are created once and reused, ensuring identity and efficiency.
Why it matters:Misunderstanding this can lead to incorrect assumptions about performance and equality checks.
Expert Zone
1
Enum constructors are private by default, preventing external instantiation and preserving the fixed set of constants.
2
You can define anonymous classes for individual enum constants to override methods uniquely, enabling polymorphic behavior.
3
The 'values()' method returns a new array copy each time, so avoid calling it repeatedly in performance-critical code.
When NOT to use
Avoid enum classes when the set of values is not fixed or needs to be extended dynamically; use sealed classes or regular classes instead. Also, for large sets of constants with complex behavior, sealed classes or interfaces may offer more flexibility.
Production Patterns
In real-world Kotlin applications, enums are used for state machines, command types, configuration options, and protocol message types. They often implement interfaces to provide behavior and are combined with 'when' expressions for clear control flow. Enums also appear in Android development for resource states and user actions.
Connections
Sealed Classes
Builds-on
Sealed classes generalize enums by allowing a fixed set of subclasses with richer data and behavior, extending the idea of fixed sets with more flexibility.
Singleton Pattern
Same pattern
Each enum constant is a singleton object, so understanding the singleton pattern helps grasp why enum constants have unique identity and are memory efficient.
Traffic Light Signals (Real-world system)
Analogy to fixed states
Traffic lights have fixed states (red, yellow, green) like enum constants, showing how enums model real-world systems with limited, known options.
Common Pitfalls
#1Using strings or integers instead of enums for fixed sets.
Wrong approach:val direction = "NORTH" if (direction == "SOUTH") { println("Going south") }
Correct approach:val direction = Direction.NORTH if (direction == Direction.SOUTH) { println("Going south") }
Root cause:Not using enums loses type safety and allows invalid values, causing bugs.
#2Forgetting to cover all enum constants in 'when' expressions without an 'else'.
Wrong approach:when(dir) { Direction.NORTH -> println("Up") Direction.SOUTH -> println("Down") }
Correct approach:when(dir) { Direction.NORTH -> println("Up") Direction.SOUTH -> println("Down") Direction.EAST -> println("Right") Direction.WEST -> println("Left") }
Root cause:Missing cases cause compile errors or require an 'else', reducing code clarity.
#3Trying to instantiate enum classes directly.
Wrong approach:val newDir = Direction("NORTHEAST")
Correct approach:Use predefined constants like Direction.NORTH or extend with sealed classes if needed.
Root cause:Enum constructors are private; enums are fixed sets, not open for new instances.
Key Takeaways
Enum classes define a fixed set of named constants as unique singleton objects, improving code safety and clarity.
Each enum constant can hold properties and methods, allowing rich data and behavior modeling.
Kotlin's 'when' expressions work seamlessly with enums, providing compile-time checks for exhaustive handling.
Enum constants are created once at runtime, ensuring efficient memory use and reliable identity comparisons.
Enums are best used for fixed sets of values; for more flexible or dynamic sets, sealed classes or other patterns are better.

Practice

(1/5)
1. What is the main purpose of an enum class in Kotlin?
easy
A. To define a function that returns multiple values
B. To group a fixed set of related constants under one type
C. To create a class that can be instantiated multiple times
D. To declare a variable that can hold any data type

Solution

  1. Step 1: Understand enum class purpose

    An enum class is designed to hold a fixed set of constants that belong together logically.
  2. Step 2: Compare options with enum usage

    Only To group a fixed set of related constants under one type correctly describes grouping related constants under one type, which is the main use of enum classes.
  3. Final Answer:

    To group a fixed set of related constants under one type -> Option B
  4. Quick Check:

    Enum class purpose = group constants [OK]
Hint: Enums group fixed constants for clarity and safety [OK]
Common Mistakes:
  • Thinking enums are for creating multiple instances
  • Confusing enums with regular classes
  • Believing enums can hold any data type variable
2. Which of the following is the correct syntax to declare an enum class named Direction with constants NORTH, SOUTH, EAST, and WEST?
easy
A. enum class Direction { NORTH, SOUTH, EAST, WEST }
B. class enum Direction { NORTH, SOUTH, EAST, WEST }
C. enum Direction { NORTH; SOUTH; EAST; WEST }
D. enum class Direction = (NORTH, SOUTH, EAST, WEST)

Solution

  1. Step 1: Recall Kotlin enum class syntax

    Kotlin enum classes start with enum class followed by the name and curly braces containing constants separated by commas.
  2. Step 2: Check each option's syntax

    enum class Direction { NORTH, SOUTH, EAST, WEST } matches the correct syntax. Options A, C, and D have incorrect keywords, punctuation, or structure.
  3. Final Answer:

    enum class Direction { NORTH, SOUTH, EAST, WEST } -> Option A
  4. Quick Check:

    Correct enum syntax = enum class Direction { NORTH, SOUTH, EAST, WEST } [OK]
Hint: Use 'enum class Name { CONST1, CONST2 }' syntax [OK]
Common Mistakes:
  • Using 'class enum' instead of 'enum class'
  • Separating constants with semicolons instead of commas
  • Assigning enum constants with '=' instead of listing
3. What will be the output of the following Kotlin code?
enum class Color { RED, GREEN, BLUE }
fun main() {
    val c = Color.GREEN
    println(c.name)
}
medium
A. green
B. Color.GREEN
C. 1
D. GREEN

Solution

  1. Step 1: Understand enum constant property 'name'

    Each enum constant has a built-in name property that returns its exact name as a string.
  2. Step 2: Analyze the code output

    The code prints c.name where c is Color.GREEN, so it prints "GREEN" exactly as declared.
  3. Final Answer:

    GREEN -> Option D
  4. Quick Check:

    Enum constant name property = GREEN [OK]
Hint: Enum.name returns constant name as string [OK]
Common Mistakes:
  • Expecting lowercase output
  • Printing enum constant directly without .name
  • Confusing ordinal number with name
4. Identify the error in this Kotlin enum class declaration:
enum class Size {
    SMALL,
    MEDIUM
    LARGE
}
medium
A. Cannot declare enum class without constructor
B. Enum constants must be lowercase
C. Missing comma after MEDIUM
D. Enum class must have at least 5 constants

Solution

  1. Step 1: Check enum constants separation

    Enum constants must be separated by commas except the last one. Here, MEDIUM is missing a comma after it.
  2. Step 2: Validate other options

    Constants can be uppercase, no constructor is required, and no minimum count is needed. So only missing comma is the error.
  3. Final Answer:

    Missing comma after MEDIUM -> Option C
  4. Quick Check:

    Enum constants separated by commas [OK]
Hint: Separate enum constants with commas except last [OK]
Common Mistakes:
  • Omitting commas between constants
  • Using lowercase for constants (not required)
  • Thinking constructor is mandatory
5. How can you add a property rgb to an enum class Color that stores the color's RGB integer value, and access it for Color.RED? Choose the correct code snippet.
hard
A. enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } fun main() { println(Color.RED.rgb) }
B. enum class Color { RED = 0xFF0000, GREEN = 0x00FF00, BLUE = 0x0000FF } fun main() { println(Color.RED.rgb) }
C. enum class Color { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } fun main() { println(Color.RED.rgb) }
D. enum class Color { RED, GREEN, BLUE } fun main() { println(Color.RED.rgb) }

Solution

  1. Step 1: Understand enum property declaration

    To add a property, declare a constructor parameter in the enum class and pass values to each constant.
  2. Step 2: Check each option for correct syntax

    enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } fun main() { println(Color.RED.rgb) } correctly declares val rgb: Int in constructor and assigns values. enum class Color { RED = 0xFF0000, GREEN = 0x00FF00, BLUE = 0x0000FF } fun main() { println(Color.RED.rgb) } uses invalid assignment syntax. enum class Color { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } fun main() { println(Color.RED.rgb) } misses constructor declaration. enum class Color { RED, GREEN, BLUE } fun main() { println(Color.RED.rgb) } has no property defined.
  3. Final Answer:

    enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } fun main() { println(Color.RED.rgb) } -> Option A
  4. Quick Check:

    Enum property via constructor = enum class Color(val rgb: Int) { RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF) } fun main() { println(Color.RED.rgb) } [OK]
Hint: Add properties via constructor parameters in enum class [OK]
Common Mistakes:
  • Trying to assign values with '=' inside enum constants
  • Not declaring constructor parameters in enum class
  • Accessing property that was never declared
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard