Unlike traditional constants declared using
public static final, enums are type-safe, can have fields, constructors, methods, and can even implement interfaces.
They are commonly used to model concepts such as days of the week, order status, user roles, log levels, and HTTP methods.
What are Enums?
Before enums were introduced, applications typically represented constant values using integer or string constants.public static final int NEW = 1;
public static final int PROCESSING = 2;
public static final int COMPLETED = 3;
This approach is not type-safe because any integer value can be assigned. Enums define a fixed set of valid values, allowing the compiler to prevent invalid assignments.
enum Status {
NEW,
PROCESSING,
COMPLETED,
CANCELLED
}
Using Enums
Enum constants are accessed using the enum type.Status status = Status.PROCESSING;
System.out.println(status);
Output:
PROCESSING
Enums should be compared using the == operator because each constant is a unique singleton instance.
if (status == Status.PROCESSING) {
System.out.println("Processing order");
}
Enums in switch
Enums integrate naturally withswitch statements.
switch (status) {
case NEW:
System.out.println("New Order");
break;
case PROCESSING:
System.out.println("Processing");
break;
case COMPLETED:
System.out.println("Completed");
break;
case CANCELLED:
System.out.println("Cancelled");
break;
}
Common Enum Methods
Every enum automatically provides several useful methods.for (Status status : Status.values()) {
System.out.println(status);
}
Status status = Status.valueOf("COMPLETED");
System.out.println(status.name());
System.out.println(status.ordinal());
The most commonly used methods are:
-
values() returns all enum constants.-
valueOf() converts a string into an enum constant.-
name() returns the constant name.-
ordinal() returns the position of the constant, starting from zero.
Avoid using
ordinal() in business logic because changing the declaration order changes its value.
Enums with Fields and Constructors
Enums can store additional information by defining fields and constructors.enum Priority {
LOW(1),
MEDIUM(2),
HIGH(3);
private final int level;
Priority(int level) {
this.level = level;
}
public int getLevel() {
return level;
}
}
Usage:
System.out.println(Priority.HIGH.getLevel());
Output:
3
Enum constructors are always private and cannot be invoked directly. Enums are also implicitly final, meaning they cannot be extended.
Enums with Methods
Enums can contain business logic just like regular classes.enum OrderStatus {
NEW,
SHIPPED,
DELIVERED;
public boolean isCompleted() {
return this == DELIVERED;
}
}
Usage:
System.out.println(
OrderStatus.DELIVERED.isCompleted()
);
Output:
true
Constant-Specific Behavior
Each enum constant can provide its own implementation of an abstract method.enum Operation {
ADD {
@Override
public int apply(int a, int b) {
return a + b;
}
},
SUBTRACT {
@Override
public int apply(int a, int b) {
return a - b;
}
};
public abstract int apply(int a, int b);
}
Usage:
System.out.println(
Operation.ADD.apply(10, 5)
);
Output:
15
This approach is often used to implement strategy-like behavior.
Enums Implementing Interfaces
Enums can implement interfaces.interface Printable {
void print();
}
enum Color implements Printable {
RED,
GREEN,
BLUE;
@Override
public void print() {
System.out.println(name());
}
}
EnumSet
EnumSet is a specialized implementation ofSet designed for enum values.
It is significantly more memory-efficient and faster than a
HashSet because it internally represents enum constants using bit vectors.
EnumSet<Status> statuses =
EnumSet.of(Status.NEW, Status.PROCESSING);
System.out.println(statuses);
Output:
[NEW, PROCESSING]
Use EnumSet whenever a collection contains only enum values.
EnumMap
EnumMap is a specialized implementation ofMap where the keys are enum constants.
It is generally faster and more memory-efficient than
HashMap because it internally stores values in an array indexed by the enum constants.
EnumMap<Status, String> messages =
new EnumMap<>(Status.class);
messages.put(Status.NEW, "Order Created");
messages.put(Status.COMPLETED, "Order Delivered");
System.out.println(messages);
Enums in switch Expressions
Modern Java supports switch expressions with enums.String message = switch (status) {
case NEW -> "New Order";
case PROCESSING -> "Processing";
case COMPLETED -> "Completed";
case CANCELLED -> "Cancelled";
};
System.out.println(message);
How Enums Work Internally
Although enums appear to be a new language construct, the compiler generates a class behind the scenes. Conceptually,enum Status {
NEW,
PROCESSING
}
is similar to:
final class Status extends Enum<Status> {
public static final Status NEW =
new Status();
public static final Status PROCESSING =
new Status();
private Status() {
}
}
Each enum constant is created only once when the class is loaded, making every constant a singleton instance.
Enum constructors are private, preventing developers from creating additional instances.
Final Notes
Enums provide a type-safe and expressive way to represent a fixed set of constants in Java.Beyond simply replacing integer or string constants, they support fields, constructors, methods, interfaces, and constant-specific behavior, making them far more powerful than traditional constants.
When used appropriately, enums improve code readability, safety, and maintainability, making them the preferred choice for modeling fixed sets of related values.