Skip to content
Dev Dump

🎯 Java Enums: Complete Guide

Think of it like a category of predefined options.

Examples:

  • Days of the week (MONDAY, TUESDAY, …)
  • Directions (NORTH, SOUTH, …)
  • Status codes (SUCCESS, ERROR)
  • Traffic signals (RED, YELLOW, GREEN)

enum EnumName {
CONSTANT1, CONSTANT2, CONSTANT3;
}
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumExample {
public static void main(String[] args) {
Day today = Day.FRIDAY;
if (today == Day.FRIDAY) {
System.out.println("Weekend is coming!");
}
// Loop through all enum values
for (Day d : Day.values()) {
System.out.println(d);
}
}
}

Output:

Weekend is coming!
MONDAY
TUESDAY
WEDNESDAY
THURSDAY
FRIDAY
SATURDAY
SUNDAY

Here, Day.values() gives an array of all constants.


Unlike final static constants, enums can have:

  • Fields (variables)
  • Constructors
  • Methods
  • Type safety
  • Built-in methods like values(), valueOf(), ordinal()

enum TrafficSignal {
RED("Stop"),
YELLOW("Get Ready"),
GREEN("Go");
private String action;
// Constructor
TrafficSignal(String action) {
this.action = action;
}
// Getter
public String getAction() {
return action;
}
}
public class EnumWithMethods {
public static void main(String[] args) {
for (TrafficSignal signal : TrafficSignal.values()) {
System.out.println(signal + " means " + signal.getAction());
}
}
}

Output:

RED means Stop
YELLOW means Get Ready
GREEN means Go

Each enum constant has its own value and behavior.


enum Direction {
NORTH, SOUTH, EAST, WEST
}
public class EnumSwitch {
public static void main(String[] args) {
Direction dir = Direction.EAST;
switch (dir) {
case NORTH:
System.out.println("Going up!");
break;
case SOUTH:
System.out.println("Going down!");
break;
case EAST:
System.out.println("Going right!");
break;
case WEST:
System.out.println("Going left!");
break;
}
}
}

🔧 Enum with Overridden Methods (Advanced)

Section titled “🔧 Enum with Overridden Methods (Advanced)”
enum Operation {
ADD {
public int apply(int x, int y) { return x + y; }
},
SUBTRACT {
public int apply(int x, int y) { return x - y; }
},
MULTIPLY {
public int apply(int x, int y) { return x * y; }
},
DIVIDE {
public int apply(int x, int y) { return x / y; }
};
public abstract int apply(int x, int y);
}
public class EnumPolymorphism {
public static void main(String[] args) {
int a = 20, b = 5;
for (Operation op : Operation.values()) {
System.out.println(op + "" + op.apply(a, b));
}
}
}

Output:

ADD → 25
SUBTRACT → 15
MULTIPLY → 100
DIVIDE → 4

Here, each enum constant overrides the apply() method differently.


Every constant inside an enum has a position (index), starting from 0. The ordinal() method returns that index number of the enum constant.

enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY
}
public class EnumOrdinal {
public static void main(String[] args) {
for (Day d : Day.values()) {
System.out.println(d + " → ordinal = " + d.ordinal());
}
}
}

Output:

MONDAY → ordinal = 0
TUESDAY → ordinal = 1
WEDNESDAY → ordinal = 2
THURSDAY → ordinal = 3
FRIDAY → ordinal = 4
  • It always starts from 0 and increases in the order the constants are declared
  • It is useful if you want to know the position of an enum constant
  • ⚠️ Caution: You should not rely heavily on ordinal() for business logic
// ❌ Bad: Relying on ordinal for business logic
enum BadPriority {
LOW, MEDIUM, HIGH, CRITICAL; // Ordinal: 0, 1, 2, 3
public int getValue() {
return ordinal() + 1; // Fragile! Returns 1, 2, 3, 4
}
}
// ✅ Good: Explicit values
enum GoodPriority {
LOW(1), MEDIUM(2), HIGH(3), CRITICAL(4);
private final int value;
GoodPriority(int value) {
this.value = value;
}
public int getValue() {
return value; // Always returns the intended value
}
}
enum Priority {
LOW, MEDIUM, HIGH, CRITICAL
}
public class EnumPriority {
public static void main(String[] args) {
Priority p = Priority.HIGH;
System.out.println("Priority: " + p);
System.out.println("Ordinal value: " + p.ordinal());
// Show all priorities with their ordinals
for (Priority priority : Priority.values()) {
System.out.println(priority + " → ordinal = " + priority.ordinal());
}
}
}

Output:

Priority: HIGH
Ordinal value: 2
LOW → ordinal = 0
MEDIUM → ordinal = 1
HIGH → ordinal = 2
CRITICAL → ordinal = 3

💡 So, ordinal() = the index (position) of the enum constant in its declaration.


  1. Enums are type-safe → you can’t assign a wrong value

    Day d = Day.MONDAY; // ✅ valid
    // Day d = 1; // ❌ error
  2. Enums can implement interfaces but cannot extend classes (because they implicitly extend java.lang.Enum)

  3. Enums can have constructors, fields, and methods

  4. Built-in enum methods:

    • values() - returns array of all enum constants
    • valueOf(String) - converts string to enum constant
    • ordinal() - returns position (0-based index)
  5. Type safety prevents invalid assignments


enum OrderStatus {
PENDING("Order is pending confirmation", 1),
CONFIRMED("Order has been confirmed", 2),
SHIPPED("Order has been shipped", 3),
DELIVERED("Order has been delivered", 4),
CANCELLED("Order has been cancelled", 5);
private final String description;
private final int statusCode;
OrderStatus(String description, int statusCode) {
this.description = description;
this.statusCode = statusCode;
}
public String getDescription() { return description; }
public int getStatusCode() { return statusCode; }
public boolean canCancel() {
return this == PENDING || this == CONFIRMED;
}
public OrderStatus next() {
return switch (this) {
case PENDING -> CONFIRMED;
case CONFIRMED -> SHIPPED;
case SHIPPED -> DELIVERED;
case DELIVERED, CANCELLED -> this; // Final states
};
}
}
public class OrderExample {
public static void main(String[] args) {
OrderStatus status = OrderStatus.PENDING;
System.out.println("Current status: " + status);
System.out.println("Description: " + status.getDescription());
System.out.println("Status code: " + status.getStatusCode());
System.out.println("Can cancel: " + status.canCancel());
// Process order
status = status.next();
System.out.println("Next status: " + status);
}
}

Example 2: Log Levels with Custom Numbering

Section titled “Example 2: Log Levels with Custom Numbering”
enum LogLevel {
DEBUG(0, "DEBUG"),
INFO(1, "INFO"),
WARN(2, "WARN"),
ERROR(3, "ERROR"),
FATAL(4, "FATAL");
private final int level;
private final String name;
LogLevel(int level, String name) {
this.level = level;
this.name = name;
}
public int getLevel() { return level; }
public String getName() { return name; }
public boolean isEnabled(LogLevel minimumLevel) {
return this.level >= minimumLevel.level;
}
public static LogLevel fromString(String level) {
try {
return LogLevel.valueOf(level.toUpperCase());
} catch (IllegalArgumentException e) {
return INFO; // Default fallback
}
}
// Compare with ordinal() vs custom level
public void showComparison() {
System.out.println(this.name + ":");
System.out.println(" Ordinal: " + this.ordinal());
System.out.println(" Custom Level: " + this.level);
}
}

ConceptSummary
Enum Declarationenum Name { CONSTANT1, CONSTANT2 }
values()Returns array of all enum constants
ordinal()Returns position (0-based index)
Type SafetyPrevents invalid constant assignments
Fields & MethodsCan have constructors, fields, and methods
Switch StatementsPerfect for switch expressions