ReviseAlgo Logo

OOP Fundamentals

Enums

Type-safe constants

Last Updated: June 25, 2026 18 min read

Enums (Enumerations) are specialized classes that define a fixed, compile-time set of constant values. Enums replace fragile string or integer codes with robust, type-safe structures, enabling compilers to detect invalid state transitions and values.

1. Learning Objectives

  • Understand the limitations of using strings/integers for static options.
  • Design enums with custom attributes, constructors, and behaviors.
  • Examine the JVM internal structure of enums as final static subclasses.

2. Problem Statement

When tracking an order's status, using raw strings (like "SHIPPED") or integers (like 2) leads to silent bugs. A developer might write "Shipped" or "DELIVRD", bypassing database matches. There is no compile-time checking to verify these values, leading to runtime failures.

3. Real-world Analogy

Think of a Traffic Light. A traffic light can only display three colors: Red, Yellow, or Green. It is physically impossible for a traffic light to display "Blue" or "Purple". The system is constrained to a fixed set of states, ensuring safety and predictability.

4. Theory

Enums in modern languages are not just lists of numbers; they are full objects. In Java, enums can have fields, constructors, and methods:

  • Fields: Assign parameters (e.g. status code, database slug) to enum items.
  • Private Constructors: Enums cannot be instantiated via the new keyword. Instances are predefined at compile-time.
  • Methods: Embed domain rules directly inside enums.

5. Visual Diagrams (UML & Memory structures)

Class Diagram

«enumeration»
OrderStatus
PENDING, SHIPPED, DELIVERED
- statusCode: int
+ getStatusCode(): int

Object Diagram

Illustrates fixed constant instances containing customized code properties:

PENDING
statusCode = 1
SHIPPED
statusCode = 2

Memory Diagram

Stack Reference

currentStatus = @0x9a8b
points to static location

Heap space (Static Constants)

@0x9a8b:
Enum instance: OrderStatus.SHIPPED
statusCode: 2

Object Lifecycle

Unlike standard objects, enums are created during class initialization when the virtual machine boots. They persist for the entire runtime of the application and are never garbage collected.

6. Syntax Explanation

  • Java: Declares enums using the enum keyword. The constructor must be private.
  • Python: Inherits from the Enum class. Properties are declared inside classes.
  • C++: Uses enum class to enforce type-safety and scope blocks.

7. Step-by-Step Implementation

Let's build a type-safe Order Status State Machine:

  • Step 1: Declare the OrderStatus enum containing constants: PENDING, SHIPPED, DELIVERED.
  • Step 2: Add private property fields statusCode and description.
  • Step 3: Write private constructor routing to initialize fields.
  • Step 4: Expose helper methods to evaluate state transition validations (e.g. blocking transition back to pending from delivered).

8. Complete Code (Mini Project)

9. Code Walkthrough

In the Java and Python code, each enum constant is an instance of the enum class. During class loading, the private constructor initializes properties statusCode and description on each predefined object instance, protecting their state from modification.

10. Execution Flow

  • The JVM initializes the OrderStatus class, allocating heap space for constants (PENDING, SHIPPED, DELIVERED).
  • Save a constant reference in stack memory.
  • Trigger transition checks comparing integer bounds.

11. Internal Working

In Java, the compiler translates enums into static subclasses of java.lang.Enum. Running javap OrderStatus reveals:

public final class OrderStatus extends java.lang.Enum {
    public static final OrderStatus PENDING;
    public static final OrderStatus SHIPPED;
    public static final OrderStatus DELIVERED;
    ...
}

Since instances are declared as public static final, they are singletons in memory, allowing safe comparison using == operators.

12. Complexity Analysis

  • Time Complexity: $O(1)$ for state checks and operations.
  • Space Complexity: $O(1)$ constant memory overhead since all instances are pre-allocated during class loading.

13. Best Practices

  • Make enum fields immutable: Set all variables to private final.
  • Compare with ==: In Java, compare enums using the == operator instead of .equals(), preventing null pointer exceptions.

14. Common Mistakes

  • Exposing public setter methods in enums, allowing internal state variables to be mutated at runtime.
  • Creating sub-instances of enums using reflection (reflection access to enum constructors is explicitly blocked by the JVM).

15. Interview Questions

Q: Can enums implement interfaces?
Answer: Yes. Enums are full-featured classes in Java, so they can implement interfaces. This is highly useful for applying strategy patterns to enum states.

16. Practice Exercises

  • Easy: Add a new status CANCELLED to the enum.
  • Medium: Implement an interface StateAction in the enum that overrides a method execute() to trigger log statements based on order states.
  • Hard: Build a dynamic parser that parses database integer inputs into corresponding enum constant items safely.

17. Challenge Problem

Design an extensible type-safe state machine for database connection states (DISCONNECTED, CONNECTING, CONNECTED, RECONNECTING) enforcing strict transition rules.

18. Summary

  • Enums provide type-safe static choices, replacing fragile integer constants.
  • In Java and Python, enums are full objects containing methods and properties.
  • Enum constants are instantiated once during class loading, serving as static singletons.

19. Cheat Sheet

Operation Standard Class Enum Class
Instantiation Unlimited via new Fixed, pre-allocated statically
Inheritance Can extend other classes Cannot extend (extends Enum implicitly)
Comparison Requires .equals() override Safe via standard ==

20. Quiz

1. Which of the following is the main benefit of using Enums?

A) They execute faster on multi-core processors
B) They restrict variable values to a type-safe, compile-time checked list of constants (Correct)
C) They allow dynamic creation of new constants at runtime

2. Where does JVM allocate enum constants?

A) Stack frame local locations
B) Heap Area, during class loading (Correct)
C) Native execution registers

3. Why should enum constructor access remain private?

A) To prevent external instantiation via the 'new' keyword (Correct)
B) It is required to make enums inherit from standard interfaces
C) To speed up class mapping

4. How should you compare enum instances in Java?

A) Using the equals() method
B) Using the == operator (Correct)
C) Using standard string comparison

5. Enums in Java implicitly inherit from which class?

A) java.lang.Object
B) java.lang.Enum (Correct)
C) java.lang.Class

6. What modifier is automatically applied to compile-time enum constants?

A) local final
B) public static final (Correct)
C) protected static

7. Why are enums considered singletons in memory?

A) Only one instance of each constant exists in memory (Correct)
B) Enums cannot have methods
C) Enums are always garbage collected instantly

8. Can enums extend other classes?

A) Yes, multiple inheritance is allowed
B) No, because they already extend java.lang.Enum (Correct)
C) Only if classes are abstract

9. In C++, why are 'enum class' structures preferred over plain 'enum'?

A) Plain enums occupy double the heap space
B) Enum class structures enforce strict scope boundaries and type safety (Correct)
C) Plain enums cannot be used inside switches

10. What does the JVM use to block instantiation of enums via reflection?

A) Private constructors checks at reflection level (Correct)
B) Restricting stack size limits
C) Restricting memory footprint allocations

21. Next Lesson Preview

In the next lesson, we will explore Interfaces to understand how to define strict code contracts and achieve complete decoupling in software engineering!