Enums

15 questions found

How do you retrieve all constants of an enum type, and how would you iterate over them?

Beginner
Every enum implicitly has a static values() method (generated automatically by the compiler) returning an array containing all the enum's constants in their declared order, which can be iterated directly with a for-each loop -- useful for populating a dropdown of options, validating input against all possible values, or any scenario needing to process every constant generically without hardcoding each one individually.
enum Season { SPRING, SUMMER, FALL, WINTER }

for (Season season : Season.values()) {
    System.out.println(season);
}
// Prints: SPRING, SUMMER, FALL, WINTER, in declaration order
Real-world example A settings UI populating a dropdown list of available themes iterates over ThemeOption.values() to generate the list of choices dynamically, automatically staying in sync if a new theme constant is added later without needing to update the UI population code itself.

Common follow-ups: Does calling values() repeatedly return the same array instance or a new copy each time, and why does that matter?;How would you convert the values() array into a List or Stream for further processing?

Collections Framework;Streams & Lambdas

What is the valueOf() method on an enum, and what happens when you pass a name that doesn't match any declared constant?

Intermediate
The implicitly-generated static valueOf(String name) method looks up and returns the enum constant whose declared identifier exactly matches the given String (case-sensitive), throwing IllegalArgumentException if no constant with that exact name exists -- useful for parsing an enum from external string input (like a configuration value or API parameter), though because it throws rather than returning a sentinel/null, callers must be prepared to catch IllegalArgumentException or validate the input beforehand if invalid values are a realistic possibility.
enum Status { ACTIVE, INACTIVE, PENDING }

Status s = Status.valueOf("ACTIVE");     // works, returns Status.ACTIVE

try {
    Status invalid = Status.valueOf("active");  // throws IllegalArgumentException -- case-sensitive!
} catch (IllegalArgumentException e) {
    System.out.println("Invalid status value");
}
Real-world example An API endpoint parsing a status query parameter into a Status enum via valueOf() wraps the call in a try-catch to return a clean 400 Bad Request error with a helpful message when a client submits an invalid or mistyped status value, rather than letting an unhandled IllegalArgumentException propagate as a generic 500 error.

Common follow-ups: Why is valueOf() case-sensitive, and what would you do to support case-insensitive lookup instead?;How does this built-in valueOf() differ from the custom fromCode()-style lookup pattern for external representations that don't match Java identifier naming?

Exceptions;RESTful Web APIs & Controllers

How would you implement a custom compareTo()-based ordering for an enum that differs from its natural declaration-order ordering, given Comparable's default implementation uses ordinal()?

Advanced
Since java.lang.Enum already implements Comparable using ordinal() (declaration order) and this implementation cannot be overridden (compareTo() in Enum is final), achieving a different sort order requires NOT relying on the enum's natural ordering at all -- instead, sort using an explicit external Comparator (via Comparator.comparing() referencing a field, or Comparator constructed from a defined priority mapping) passed to Collections.sort() or a stream's sorted() method, keeping the enum's own natural/declaration ordering untouched while still achieving the desired custom sort order for a specific use case.
enum Priority { LOW, MEDIUM, HIGH, CRITICAL }  // natural order: LOW < MEDIUM < HIGH < CRITICAL via ordinal

// Need CRITICAL first, LOW last for a specific report -- can't override compareTo(), so use an explicit Comparator
List<Priority> priorities = new ArrayList<>(List.of(Priority.values()));
priorities.sort(Comparator.comparing(Priority::ordinal).reversed());
// Or an entirely custom priority mapping via Comparator.comparing(p -> customPriorityMap.get(p))
Real-world example A ticket triage report needing CRITICAL-first ordering (opposite of the enum's natural LOW-to-CRITICAL declaration order used everywhere else in the codebase) sorts using an explicit reversed Comparator for just that one report, leaving the enum's own natural ordering (relied upon elsewhere for consistent default behavior) completely unaffected.

Common follow-ups: Why did the JDK designers make Enum's compareTo() final rather than allowing it to be overridden?;What's the risk of an enum's natural ordering silently changing if constants are reordered, given compareTo() is ordinal-based?

Collections Framework;Streams & Lambdas

How would you use an enum to represent a fixed set of configuration keys combined with a shared lookup method, avoiding scattered String literal keys throughout a codebase?

Intermediate
Representing configuration keys as enum constants (rather than raw String literals scattered throughout the codebase) provides compile-time safety against typos (a misspelled String key silently returns null/default at runtime, while a misspelled enum reference simply fails to compile), IDE autocomplete support for discovering all valid keys, and a natural single place to attach metadata (default value, expected type, description) to each key via enum fields.
public enum ConfigKey {
    MAX_CONNECTIONS("max.connections", "100"),
    TIMEOUT_MS("timeout.ms", "5000");

    private final String propertyName;
    private final String defaultValue;
    ConfigKey(String propertyName, String defaultValue) {
        this.propertyName = propertyName; this.defaultValue = defaultValue;
    }
    public String propertyName() { return propertyName; }
    public String defaultValue() { return defaultValue; }
}

String timeout = System.getProperty(ConfigKey.TIMEOUT_MS.propertyName(), ConfigKey.TIMEOUT_MS.defaultValue());
Real-world example A large application replaces dozens of scattered raw String configuration key literals (prone to typos) with a centralized ConfigKey enum, catching an entire class of configuration-key typo bugs at compile time that previously would have silently fallen back to default values at runtime without any warning.

Common follow-ups: How would you extend this pattern to also validate or parse the configuration value's expected type (int, boolean, etc.) per key?;What's the trade-off of this enum-based approach versus a more dynamic, externally-configurable key system?

Configuration & Options Pattern;Java Fundamentals: Syntax Data Types & Operators

How would you handle adding behavior to an enum where the number of constants might grow very large or needs to be data-driven rather than hardcoded at compile time, and why might a class-based registry be more appropriate in that scenario?

Advanced
Enums are fundamentally a CLOSED, compile-time-fixed set of constants -- appropriate when the set of values is genuinely stable and known at compile time (like days of the week, or a fixed set of HTTP methods), but poorly suited to scenarios where the set of constants needs to grow dynamically at runtime (loaded from a database, a plugin system, or user configuration) since enum constants can't be added without recompiling the enum's source code itself -- for genuinely dynamic, extensible sets of named values with associated behavior, a regular class combined with a Map-based registry (mapping a String/code to an instance) provides the same lookup-by-key convenience while supporting runtime extensibility that a true enum structurally cannot.
// NOT well-suited to enum: currency codes that might be extended by configuration at runtime
public final class Currency {
    private static final Map<String, Currency> REGISTRY = new ConcurrentHashMap<>();
    private final String code;
    private Currency(String code) { this.code = code; }

    public static Currency register(String code) {
        return REGISTRY.computeIfAbsent(code, Currency::new);  // can grow dynamically, unlike an enum
    }
    public static Currency of(String code) { return REGISTRY.get(code); }
}
Real-world example A multi-tenant SaaS platform allowing each customer organization to define their own custom set of order-status values (impossible to know all of them at compile time) uses a class-based registry pattern with a Map-backed lookup instead of an enum, since new status values need to be added dynamically per-tenant without requiring a code deployment.

Common follow-ups: What functionality do you lose by switching from a true enum to this class-based registry pattern (like switch-statement exhaustiveness checking)?;How would EnumMap/EnumSet's performance benefits compare to this Map-based registry approach?

Design Patterns in Java;Configuration & Options Pattern

Showing 11–15 of 15