AI InterviewSearch…Search problems, topics, or pages…Ctrl KGet started
Skip to content

10 Enums & records / Lesson 1 of 5

Enums — a fixed set of named instances

13 min · +10 XP · 2 exercises · 5 questions

Read the text13 min
Exercises0/2
Quiz5 q

Quick answer

What is an enum in Java?

An enum in Java is a special class with a fixed set of named instances, declared as enum Day { MONDAY, TUESDAY, … }. Each constant is a single object created by the JVM, so enums are type-safe — a method taking a Day cannot be passed 7 — and are compared with ==. Every enum gets values(), valueOf, name() and ordinal(), and works in switch.

Before enums, a "day of the week" was int DAY_MONDAY = 1 and nothing stopped you passing 7 or 42. A Java enum is a class with a fixed set of instances created by the JVM, each a named constant, type-safe and comparable. Every enum you write is a full class — the next lesson adds fields and methods — but even the plain form solves most "a value from a known set" problems. This lesson is the plain form and the machinery every enum gets for free.

Declaring

public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }

Day d = Day.FRIDAY;
Day bad = new Day();          // compile error: enum types may not be instantiated

Day is a class that extends java.lang.Enum<Day> implicitly; the seven constants are its only instances, public static final, created once when the class initialises. Constant names are UPPER_SNAKE_CASE. An enum can be top-level or nested (implicitly static). It is implicitly final — unless constants have bodies (next lesson) — and cannot extend another class (it already extends Enum), though it may implement interfaces.

What every enum has

Day.values()                  // Day[] of all constants, in declaration order — a fresh array each call
Day.valueOf("FRIDAY")         // FRIDAY; throws IllegalArgumentException for "friday" or "Fri"
d.name()                      // "FRIDAY" — the identifier, exactly
d.ordinal()                   // 4 — position in declaration order, zero-based
d.toString()                  // "FRIDAY" by default; overridable
d.compareTo(Day.MONDAY)       // positive — by ordinal; enums are Comparable in declaration order
d == Day.FRIDAY               // true — the idiomatic comparison
d.equals(Day.FRIDAY)          // also true; == is preferred (null-safe, compile-checked)
d.getDeclaringClass()         // Day.class
Enum.valueOf(Day.class, "MONDAY")   // the generic form

== is correct for enums because each constant is a single instance: no equals override to forget, no NullPointerException when the left side is null, and a type error if you compare against a different enum. Do not write d.equals(…) out of string habit.

Enums in switch

String kind = switch (d) {
    case SATURDAY, SUNDAY -> "weekend";
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "weekday";
};                               // exhaustive over the enum: no default needed

Case labels are the bare constant names (SATURDAY, not Day.SATURDAY). A switch expression covering every constant needs no default, and then adding a constant breaks the compile at every such switch — the safety that makes enums better than integer codes. A switch statement does not check exhaustiveness; a null selector throws NullPointerException in both.

Parsing and printing

valueOf is exact and case-sensitive. For user input, normalise first (Day.valueOf(s.trim().toUpperCase(Locale.ROOT))) and catch IllegalArgumentException, or write a lenient static lookup (next lesson). Never rely on ordinal() for persistence — reordering the constants changes every stored number. Store name(), and make renaming a constant a deliberate migration.

Comparing and sorting

Enums sort by ordinal — declaration order — with compareTo, Collections.sort, TreeSet. Declare constants in the order that makes sense as a ranking (LOW, MEDIUM, HIGH) and compareTo becomes meaningful. Comparator.comparing(Enum::name) sorts alphabetically if needed.

Iterating

for (Day d : Day.values()) { … }
Arrays.stream(Day.values()).filter(…)
EnumSet.allOf(Day.class)         // a Set view, faster than the array for membership tests (lesson 3)

values() clones the internal array each call — cheap for seven constants, but hoist it out of a hot loop or use EnumSet.

Enums are singletons — properly

Each constant is exactly one object per JVM (per class loader). The JVM guarantees this through serialization (readResolve is built in) and reflection (Constructor.newInstance refuses enums). That makes a one-constant enum the most robust singleton in Java:

public enum Registry {
    INSTANCE;
    private final Map<String, Object> entries = new HashMap<>();
    public void put(String k, Object v) { entries.put(k, v); }
}
Registry.INSTANCE.put("x", 1);

Type safety versus constants

static final int RED = 0, GREEN = 1;
paint(2);                        // compiles; meaningless

enum Color { RED, GREEN }
paint(Color.BLUE);               // compile error: no such constant
paint(2);                        // compile error: int is not a Color

The compiler knows the complete set, checks every use, and the debugger shows GREEN instead of 1. Use enums for anything that is "one of a known set": states, kinds, levels, units, commands, directions.

Common mistakes

MistakeEffect
Day.valueOf("friday")IllegalArgumentException — exact name required
Persisting ordinal()Silent corruption after reordering
switch on a null enumNullPointerException
case Day.MONDAY:Compile error — unqualified names only (Java 21 relaxes this)
Comparing enums from different types with ==Compile error — a feature
Mutable static state in an enumGlobal mutable state with a nice name

Interview angle

  • "Can an enum extend a class?" No — it already extends Enum; it can implement interfaces.
  • "== or equals for enums?" ==: single instances, null-safe, type-checked.
  • "What does ordinal() return and should you store it?" Declaration index; no — store name().
  • "Why is an enum a good singleton?" One instance guaranteed by the JVM, serialization- and reflection-safe.
  • "Is a switch over an enum exhaustive without default?" A switch expression covering all constants is; a statement is not checked.

Key takeaways

  • An enum is a class with a fixed set of named, singleton instances; compare with ==.
  • Free machinery: values(), valueOf, name(), ordinal(), compareTo by declaration order, toString.
  • Switch expressions over all constants need no default and break on new constants — the point.
  • Store name(), never ordinal(); valueOf is exact and throws.

Common questions

Should you use == or equals to compare enums in Java?

Use ==. Each enum constant is a single instance, so == is correct, never throws NullPointerException when the left side is null, and is a compile error when the two sides are different enum types. equals gives the same answer without those checks.

What does valueOf do in a Java enum?

Day.valueOf("FRIDAY") returns the constant with exactly that name. It is case-sensitive and throws IllegalArgumentException for anything else, including "friday" or "Fri", so normalise user input first, for example with toUpperCase(Locale.ROOT), and catch the exception.

What is ordinal() in a Java enum, and should you store it?

ordinal() returns a constant's zero-based position in declaration order. Do not persist it: reordering or inserting constants silently changes every stored number. Store name() instead, and treat renaming a constant as a deliberate migration.

Does a switch on an enum need a default case in Java?

A switch expression that covers every constant needs no default, and adding a constant then breaks compilation at every such switch until it is handled. A switch statement is not checked for exhaustiveness, and a null selector throws NullPointerException in both.

Why is an enum the best way to create a singleton in Java?

A one-constant enum such as enum Registry { INSTANCE; } is guaranteed a single instance by the JVM: serialization cannot create a second copy and reflection refuses to instantiate enums. Effective Java recommends it as the most robust singleton.

Mark as readSign in to keep your place.

What Is an Enum in Java? Enum Methods, Switch and Singletons

A Java enum is a class with a fixed set of named instances. Its values, valueOf, name and ordinal methods, comparing with ==, exhaustive switch and singletons.

  • Course: Java study plan
  • Module: Enums & records
  • Kind: Lesson
  • Reading time: 13 min
  • Runtime: OpenJDK 18

What is an enum in Java?

An enum in Java is a special class with a fixed set of named instances, declared as enum Day { MONDAY, TUESDAY, … }. Each constant is a single object created by the JVM, so enums are type-safe — a method taking a Day cannot be passed 7 — and are compared with ==. Every enum gets values(), valueOf, name() and ordinal(), and works in switch.

Lesson

Before enums, a "day of the week" was int DAY_MONDAY = 1 and nothing stopped you passing 7 or 42. A Java enum is a class with a fixed set of instances created by the JVM, each a named constant, type-safe and comparable. Every enum you write is a full class — the next lesson adds fields and methods — but even the plain form solves most "a value from a known set" problems. This lesson is the plain form and the machinery every enum gets for free.

Declaring

public enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }

Day d = Day.FRIDAY;
Day bad = new Day();          // compile error: enum types may not be instantiated

Day is a class that extends java.lang.Enum<Day> implicitly; the seven constants are its only instances, public static final, created once when the class initialises. Constant names are UPPER_SNAKE_CASE. An enum can be top-level or nested (implicitly static). It is implicitly final — unless constants have bodies (next lesson) — and cannot extend another class (it already extends Enum), though it may implement interfaces.

What every enum has

Day.values()                  // Day[] of all constants, in declaration order — a fresh array each call
Day.valueOf("FRIDAY")         // FRIDAY; throws IllegalArgumentException for "friday" or "Fri"
d.name()                      // "FRIDAY" — the identifier, exactly
d.ordinal()                   // 4 — position in declaration order, zero-based
d.toString()                  // "FRIDAY" by default; overridable
d.compareTo(Day.MONDAY)       // positive — by ordinal; enums are Comparable in declaration order
d == Day.FRIDAY               // true — the idiomatic comparison
d.equals(Day.FRIDAY)          // also true; == is preferred (null-safe, compile-checked)
d.getDeclaringClass()         // Day.class
Enum.valueOf(Day.class, "MONDAY")   // the generic form

== is correct for enums because each constant is a single instance: no equals override to forget, no NullPointerException when the left side is null, and a type error if you compare against a different enum. Do not write d.equals(…) out of string habit.

Enums in switch

String kind = switch (d) {
    case SATURDAY, SUNDAY -> "weekend";
    case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> "weekday";
};                               // exhaustive over the enum: no default needed

Case labels are the bare constant names (SATURDAY, not Day.SATURDAY). A switch expression covering every constant needs no default, and then adding a constant breaks the compile at every such switch — the safety that makes enums better than integer codes. A switch statement does not check exhaustiveness; a null selector throws NullPointerException in both.

Parsing and printing

valueOf is exact and case-sensitive. For user input, normalise first (Day.valueOf(s.trim().toUpperCase(Locale.ROOT))) and catch IllegalArgumentException, or write a lenient static lookup (next lesson). Never rely on ordinal() for persistence — reordering the constants changes every stored number. Store name(), and make renaming a constant a deliberate migration.

Comparing and sorting

Enums sort by ordinal — declaration order — with compareTo, Collections.sort, TreeSet. Declare constants in the order that makes sense as a ranking (LOW, MEDIUM, HIGH) and compareTo becomes meaningful. Comparator.comparing(Enum::name) sorts alphabetically if needed.

Iterating

for (Day d : Day.values()) { … }
Arrays.stream(Day.values()).filter(…)
EnumSet.allOf(Day.class)         // a Set view, faster than the array for membership tests (lesson 3)

values() clones the internal array each call — cheap for seven constants, but hoist it out of a hot loop or use EnumSet.

Enums are singletons — properly

Each constant is exactly one object per JVM (per class loader). The JVM guarantees this through serialization (readResolve is built in) and reflection (Constructor.newInstance refuses enums). That makes a one-constant enum the most robust singleton in Java:

public enum Registry {
    INSTANCE;
    private final Map<String, Object> entries = new HashMap<>();
    public void put(String k, Object v) { entries.put(k, v); }
}
Registry.INSTANCE.put("x", 1);

Type safety versus constants

static final int RED = 0, GREEN = 1;
paint(2);                        // compiles; meaningless

enum Color { RED, GREEN }
paint(Color.BLUE);               // compile error: no such constant
paint(2);                        // compile error: int is not a Color

The compiler knows the complete set, checks every use, and the debugger shows GREEN instead of 1. Use enums for anything that is "one of a known set": states, kinds, levels, units, commands, directions.

Common mistakes

MistakeEffect
Day.valueOf("friday")IllegalArgumentException — exact name required
Persisting ordinal()Silent corruption after reordering
switch on a null enumNullPointerException
case Day.MONDAY:Compile error — unqualified names only (Java 21 relaxes this)
Comparing enums from different types with ==Compile error — a feature
Mutable static state in an enumGlobal mutable state with a nice name

Interview angle

  • "Can an enum extend a class?" No — it already extends Enum; it can implement interfaces.
  • "== or equals for enums?" ==: single instances, null-safe, type-checked.
  • "What does ordinal() return and should you store it?" Declaration index; no — store name().
  • "Why is an enum a good singleton?" One instance guaranteed by the JVM, serialization- and reflection-safe.
  • "Is a switch over an enum exhaustive without default?" A switch expression covering all constants is; a statement is not checked.

Key takeaways

  • An enum is a class with a fixed set of named, singleton instances; compare with ==.
  • Free machinery: values(), valueOf, name(), ordinal(), compareTo by declaration order, toString.
  • Switch expressions over all constants need no default and break on new constants — the point.
  • Store name(), never ordinal(); valueOf is exact and throws.

Common questions

Should you use == or equals to compare enums in Java?

Use ==. Each enum constant is a single instance, so == is correct, never throws NullPointerException when the left side is null, and is a compile error when the two sides are different enum types. equals gives the same answer without those checks.

What does valueOf do in a Java enum?

Day.valueOf("FRIDAY") returns the constant with exactly that name. It is case-sensitive and throws IllegalArgumentException for anything else, including "friday" or "Fri", so normalise user input first, for example with toUpperCase(Locale.ROOT), and catch the exception.

What is ordinal() in a Java enum, and should you store it?

ordinal() returns a constant's zero-based position in declaration order. Do not persist it: reordering or inserting constants silently changes every stored number. Store name() instead, and treat renaming a constant as a deliberate migration.

Does a switch on an enum need a default case in Java?

A switch expression that covers every constant needs no default, and adding a constant then breaks compilation at every such switch until it is handled. A switch statement is not checked for exhaustiveness, and a null selector throws NullPointerException in both.

Why is an enum the best way to create a singleton in Java?

A one-constant enum such as enum Registry { INSTANCE; } is guaranteed a single instance by the JVM: serialization cannot create a second copy and reflection refuses to instantiate enums. Effective Java recommends it as the most robust singleton.

Exercises

Days and their kinds

Declare enum Day { MONDAY, …, SUNDAY }. Read an integer n and n tokens. For each token: parse it with Day.valueOf after trimming and upper-casing; if it is not a day print <token> unknown; otherwise print <NAME> <ordinal> <weekday|weekend> next=<the following day, wrapping from SUNDAY to MONDAY>. Use a switch expression over the enum for weekday/weekend and values() with the ordinal for next.

Example: 3 then friday Sunday funday →

FRIDAY 4 weekday next=SATURDAY
SUNDAY 6 weekend next=MONDAY
funday unknown

Traffic light cycle

Declare enum Light { RED, GREEN, YELLOW } with a method Light next() that cycles RED → GREEN → YELLOW → RED using values() and ordinal(). Read a starting colour and an integer k; print the light after each of k steps, one per line, then ordinal=<ordinal of the final light>. A starting colour that is not a constant makes valueOf throw — catch it and print unknown light: <text> instead.

Example: RED 4 →

GREEN
YELLOW
RED
GREEN
ordinal=1

In this module: Enums & records

← Checkpoint — Interfaces · Enums with fields, constructors and behaviour →