Java Enum
Special classes for defining collections of constants
📋 What is an Enum?
Enum is a special class that represents a group of constants. It provides type safety, prevents invalid values, and makes code more readable and maintainable.
// Simple enum definition
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Enum Features
Type Safety
Prevents invalid constant values
enum Status {
ACTIVE, INACTIVE, PENDING
}
Built-in Methods
Comes with useful methods
Status.valueOf("ACTIVE");
Status.values();
status.ordinal();
Constructor Support
Can have fields and constructors
enum Size {
SMALL(10), MEDIUM(20), LARGE(30);
private int value;
}
Methods
Can have custom methods
enum Planet {
EARTH(5.976e+24);
double getMass() { return mass; }
}
🔹 Basic Enum Usage
Creating and using simple enums:
// Define enum
enum TrafficLight {
RED, YELLOW, GREEN
}
public class EnumExample {
public static void main(String[] args) {
// Using enum constants
TrafficLight light = TrafficLight.RED;
System.out.println("Current light: " + light);
// Switch statement with enum
switch (light) {
case RED:
System.out.println("Stop!");
break;
case YELLOW:
System.out.println("Caution!");
break;
case GREEN:
System.out.println("Go!");
break;
}
// Built-in methods
System.out.println("Ordinal of RED: " + TrafficLight.RED.ordinal());
System.out.println("All values: ");
for (TrafficLight tl : TrafficLight.values()) {
System.out.println("- " + tl);
}
// valueOf method
TrafficLight fromString = TrafficLight.valueOf("GREEN");
System.out.println("From string: " + fromString);
}
}
Output:
Current light: RED Stop! Ordinal of RED: 0 All values: - RED - YELLOW - GREEN From string: GREEN
🔹 Enum with Fields and Constructor
Enums can have fields, constructors, and methods:
enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6);
private final double mass; // in kilograms
private final double radius; // in meters
// Constructor
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
// Methods
public double getMass() {
return mass;
}
public double getRadius() {
return radius;
}
// Calculate surface gravity
public double surfaceGravity() {
final double G = 6.67300E-11;
return G * mass / (radius * radius);
}
// Calculate weight on this planet
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
public class PlanetExample {
public static void main(String[] args) {
double earthWeight = 70; // kg
double mass = earthWeight / Planet.EARTH.surfaceGravity();
System.out.println("Your weight on different planets:");
for (Planet p : Planet.values()) {
System.out.printf("Weight on %s: %.2f kg%n",
p, p.surfaceWeight(mass));
}
System.out.println("\nPlanet details:");
Planet earth = Planet.EARTH;
System.out.printf("Earth mass: %.2e kg%n", earth.getMass());
System.out.printf("Earth radius: %.2e m%n", earth.getRadius());
}
}
Output:
Your weight on different planets: Weight on MERCURY: 26.36 kg Weight on VENUS: 63.21 kg Weight on EARTH: 70.00 kg Weight on MARS: 26.56 kg Planet details: Earth mass: 5.98e+24 kg Earth radius: 6.38e+06 m
🔹 Enum with Abstract Methods
Enums can have abstract methods that each constant must implement:
enum Operation {
PLUS("+") {
public double apply(double x, double y) {
return x + y;
}
},
MINUS("-") {
public double apply(double x, double y) {
return x - y;
}
},
MULTIPLY("*") {
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
public double apply(double x, double y) {
return x / y;
}
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return symbol;
}
// Abstract method - each constant must implement
public abstract double apply(double x, double y);
@Override
public String toString() {
return symbol;
}
}
public class CalculatorExample {
public static void main(String[] args) {
double x = 10.0;
double y = 3.0;
System.out.println("Calculator operations:");
for (Operation op : Operation.values()) {
double result = op.apply(x, y);
System.out.printf("%.1f %s %.1f = %.2f%n",
x, op, y, result);
}
// Using specific operation
Operation multiply = Operation.MULTIPLY;
System.out.println("\nSpecific operation:");
System.out.printf("5 %s 4 = %.1f%n",
multiply, multiply.apply(5, 4));
}
}
Output:
Calculator operations: 10.0 + 3.0 = 13.00 10.0 - 3.0 = 7.00 10.0 * 3.0 = 30.00 10.0 / 3.0 = 3.33 Specific operation: 5 * 4 = 20.0
🔹 Real-World Example: Order Status
A practical example using enums for order management:
enum OrderStatus {
PENDING("Order received, processing...") {
public OrderStatus next() {
return CONFIRMED;
}
},
CONFIRMED("Order confirmed, preparing...") {
public OrderStatus next() {
return SHIPPED;
}
},
SHIPPED("Order shipped, in transit...") {
public OrderStatus next() {
return DELIVERED;
}
},
DELIVERED("Order delivered successfully!") {
public OrderStatus next() {
return this; // Final state
}
},
CANCELLED("Order cancelled") {
public OrderStatus next() {
return this; // Final state
}
};
private final String description;
OrderStatus(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
public abstract OrderStatus next();
public boolean canCancel() {
return this == PENDING || this == CONFIRMED;
}
}
class Order {
private String orderId;
private OrderStatus status;
public Order(String orderId) {
this.orderId = orderId;
this.status = OrderStatus.PENDING;
}
public void processNext() {
status = status.next();
System.out.println("Order " + orderId + ": " + status.getDescription());
}
public void cancel() {
if (status.canCancel()) {
status = OrderStatus.CANCELLED;
System.out.println("Order " + orderId + " cancelled");
} else {
System.out.println("Cannot cancel order " + orderId + " in " + status + " status");
}
}
public OrderStatus getStatus() {
return status;
}
}
public class OrderExample {
public static void main(String[] args) {
Order order = new Order("ORD-001");
System.out.println("Order lifecycle:");
System.out.println("Initial: " + order.getStatus().getDescription());
// Process through states
order.processNext(); // CONFIRMED
order.processNext(); // SHIPPED
// Try to cancel (should fail)
order.cancel();
order.processNext(); // DELIVERED
order.processNext(); // Still DELIVERED
System.out.println("\nNew order cancellation:");
Order order2 = new Order("ORD-002");
order2.cancel(); // Should succeed
}
}
Output:
Order lifecycle: Initial: Order received, processing... Order ORD-001: Order confirmed, preparing... Order ORD-001: Order shipped, in transit... Cannot cancel order ORD-001 in SHIPPED status Order ORD-001: Order delivered successfully! Order ORD-001: Order delivered successfully! New order cancellation: Order ORD-002 cancelled
🔹 Enum Best Practices
Guidelines for effective enum usage:
Best Practices:
- Use for fixed sets: Days, months, status values, etc.
- Make fields final: Enum constants should be immutable
- Use descriptive names: ACTIVE instead of A, PENDING instead of P
- Implement toString(): For better string representation
- Consider EnumSet/EnumMap: For collections of enums
When to Use Enums:
- Fixed set of constants (colors, directions, states)
- Type-safe alternatives to int constants
- Switch statement cases
- Configuration options