View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

Complete Guide to Java Enum in Java: Types and Best Practices

Updated on 19/05/20254,058 Views

Enums in Java are a special data type that lets you define a fixed set of constants. They help make your code more readable, maintainable, and type-safe. Instead of static final variables, enums offer a cleaner and more organized way to group related constants.

Introduced in Java 5, enums are much more powerful than they appear. They are full-fledged classes that can include fields, methods, and constructors. This allows developers to add behavior to enum values and use them meaningfully. Enums are commonly used to represent fixed sets such as days of the week, directions, or status codes.

By using enums, you avoid hard-coded values like magic numbers or strings, making your code easier to manage and less error-prone. This blog will explore basic and advanced enums, including enum methods, constructors, and best practices. Many software engineering courses emphasize enums as an essential topic for writing better Java code.

Basics of Enum in Java

What is an Enum Data Type in Java?

An enum data type in Java is a special class type representing a group of constants (unchangeable variables). Enums are implicitly final and static, which means they can't be extended (inherited) and their constants are accessible directly through the enum type name.

The key features of enum in Java include:

  • Type safety: Compiler ensures only valid enum values are used
  • Namespace: Enum constants are scoped within their enum type
  • Singleton pattern: Each enum constant is instantiated only once
  • Serialization: Enums handle their own serialization
  • Comparable interface: Enums implement Comparable by default

Also read: Data Types in Java: Primitive & Non-Primitive Data Types

When to Use Enum in Java

You should consider using an enum in Java in the following scenarios:

  • When you need to represent a fixed set of constants
  • When you want compile-time type checking for a set of values
  • When you need to associate data or behavior with constants
  • When you want to iterate through a predefined set of values
  • When you need to group related constants together

Basic Enum Declaration in Java

The syntax for a basic enum declaration in Java is straightforward:

// Basic enum declaration in Java
public enum Season {
    WINTER,
    SPRING,
    SUMMER,
    FALL
}

In this example, WINTER, SPRING, SUMMER, and FALL are enum constants. Each constant is an instance of the Season enum type. By convention, enum constants are written in uppercase letters to distinguish them from variables.

Enhance your abilities through these best-in-class certifications.

How to Create Enum in Java

To create and use an enum in Java, follow these steps:

  1. Define the enum type using the enum keyword
  2. List all possible values as constants
  3. Add any fields, constructors, or methods if needed
  4. Use the enum in your code by referencing its constants

Let's look at a simple example:

// How to create enum in Java
public class EnumExample {
    // Creating the enum
    public enum Day {
        MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    }
    
    public static void main(String[] args) {
        // Using the enum
        Day today = Day.WEDNESDAY;
        System.out.println("Today is: " + today);
        
        // Comparing enum values (using == is safe with enums)
        if (today == Day.WEDNESDAY) {
            System.out.println("It's middle of the week!");
        }
    }
}

Output:

Today is: WEDNESDAY

It's middle of the week!

Must read: Collection Framework in Java

Enum with Values in Java

Adding Fields to Enum in Java

One of the powerful features of enum in Java is that you can associate data with each enum constant. This allows you to add more information to your constants beyond just their names.

Here's how to create an enum with values in Java:

// Enum with values in Java
public 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),
    JUPITER(1.9e+27, 7.1492e7),
    SATURN(5.688e+26, 6.0268e7),
    URANUS(8.686e+25, 2.5559e7),
    NEPTUNE(1.024e+26, 2.4746e7);

    private final double mass;   // in kilograms
    private final double radius; // in meters
    
    // Enum constructor
    Planet(double mass, double radius) {
        this.mass = mass;
        this.radius = radius;
    }
    
    // Getters
    public double getMass() {
        return mass;
    }
    
    public double getRadius() {
        return radius;
    }
    
    // Custom method
    public double surfaceGravity() {
        double G = 6.67300E-11; // universal gravitational constant
        return G * mass / (radius * radius);
    }
    
    public double surfaceWeight(double otherMass) {
        return otherMass * surfaceGravity();
    }
}

In this example, each planet has associated mass and radius values. We use an enum constructor in Java to initialize these fields for each constant.

How to Use Enum Constructor in Java

An enum constructor in Java is a special type of constructor that's called when enum constants are created. Here are the key points about enum with constructor in Java:

  1. Constructors in enums are always private (explicitly or implicitly)
  2. Constructors are called once for each enum constant
  3. Constructor parameters are supplied in the enum declaration
  4. Constructors are called in the order enum constants are defined

Let's see another example of an enum constructor in Java:

// Enum with constructor in Java
public enum CoffeeSize {
    // Enum constants with constructor arguments
    SMALL(8),
    MEDIUM(12),
    LARGE(16),
    EXTRA_LARGE(20);
    
    private final int ounces;
    
    // Private constructor
    private CoffeeSize(int ounces) {
        this.ounces = ounces;
    }
    
    public int getOunces() {
        return ounces;
    }
}

public class CoffeeShop {
    public static void main(String[] args) {
        CoffeeSize size = CoffeeSize.MEDIUM;
        System.out.println("Coffee size: " + size + " (" + size.getOunces() + " oz)");
        
        // Using values() method to iterate through all enum constants
        System.out.println("\nAvailable sizes:");
        for (CoffeeSize cs : CoffeeSize.values()) {
            System.out.println(cs + " - " + cs.getOunces() + " oz");
        }
    }
}

Output:

Coffee size: MEDIUM (12 oz)

Available sizes:

SMALL - 8 oz

MEDIUM - 12 oz

LARGE - 16 oz

EXTRA_LARGE - 20 oz

Also check: Design Patterns in Java

Advanced Enum Features in Java

Enum Methods in Java

Every enum in Java automatically inherits from java.lang.Enum class, which provides several useful methods:

Method

Description

values()

Returns an array containing all enum constants

valueOf(String name)

Returns the enum constant with the specified name

name()

Returns the exact name of this enum constant

ordinal()

Returns the position of the enum constant (0-based)

compareTo(E o)

Compares enum constants based on their ordinal values

equals(Object other)

Compares enum references for equality

Here's an example demonstrating these built-in methods:

// Exploring built-in enum methods in Java
public class EnumMethodsDemo {
    public enum TrafficLight {
        RED, YELLOW, GREEN
    }
    
    public static void main(String[] args) {
        // Using values() method
        System.out.println("All traffic light states:");
        for (TrafficLight light : TrafficLight.values()) {
            System.out.println(light);
        }
        
        // Using valueOf() method
        TrafficLight light1 = TrafficLight.valueOf("RED");
        System.out.println("\nlight1: " + light1);
        
        // Using name() method
        System.out.println("light1 name: " + light1.name());
        
        // Using ordinal() method
        System.out.println("light1 ordinal: " + light1.ordinal());
        
        // Using compareTo() method
        TrafficLight light2 = TrafficLight.GREEN;
        System.out.println("light1.compareTo(light2): " + light1.compareTo(light2));
        
        // Using == for comparison (safe with enums)
        System.out.println("light1 == TrafficLight.RED: " + (light1 == TrafficLight.RED));
    }
}

Output:

All traffic light states:

RED

YELLOW

GREEN

light1: RED

light1 name: RED

light1 ordinal: 0

light1.compareTo(light2): -2

light1 == TrafficLight.RED: true

Must explore: Comparable and Comparator in Java

Custom Methods in Enum

You can add custom methods to an enum in Java, just like in a regular class. This allows you to encapsulate behavior specific to each enum constant.

// Enum with custom methods in Java
public enum Operation {
    ADD("+") {
        @Override
        public double apply(double x, double y) {
            return x + y;
        }
    },
    SUBTRACT("-") {
        @Override
        public double apply(double x, double y) {
            return x - y;
        }
    },
    MULTIPLY("*") {
        @Override
        public double apply(double x, double y) {
            return x * y;
        }
    },
    DIVIDE("/") {
        @Override
        public double apply(double x, double y) {
            if (y == 0) {
                throw new ArithmeticException("Division by zero");
            }
            return x / y;
        }
    };
    
    private final String symbol;
    
    Operation(String symbol) {
        this.symbol = symbol;
    }
    
    public String getSymbol() {
        return symbol;
    }
    
    // Abstract method to be implemented by each enum constant
    public abstract double apply(double x, double y);
}

public class CalculatorDemo {
    public static void main(String[] args) {
        double x = 10;
        double y = 5;
        
        for (Operation op : Operation.values()) {
            System.out.printf("%f %s %f = %f%n", x, op.getSymbol(), y, op.apply(x, y));
        }
    }
}

Output:

10.000000 + 5.000000 = 15.000000

10.000000 - 5.000000 = 5.000000

10.000000 * 5.000000 = 50.000000

10.000000 / 5.000000 = 2.000000

Implementing Interfaces with Enum

An enum in Java can implement interfaces, which provides a way to ensure that all enum constants provide implementations for the interface methods.

// Enum implementing an interface in Java
interface Describable {
    String getDescription();
}

public enum PaymentMethod implements Describable {
    CREDIT_CARD("Payment using credit card"),
    DEBIT_CARD("Payment using debit card"),
    PAYPAL("Payment using PayPal"),
    CRYPTO("Payment using cryptocurrency"),
    BANK_TRANSFER("Payment using bank transfer");
    
    private final String description;
    
    PaymentMethod(String description) {
        this.description = description;
    }
    
    // Implementing the interface method
    @Override
    public String getDescription() {
        return description;
    }
}

public class PaymentDemo {
    public static void main(String[] args) {
        System.out.println("Available payment methods:");
        for (PaymentMethod method : PaymentMethod.values()) {
            System.out.println("- " + method + ": " + method.getDescription());
        }
    }
}

Output:

Available payment methods:

- CREDIT_CARD: Payment using credit card

- DEBIT_CARD: Payment using debit card

- PAYPAL: Payment using PayPal

- CRYPTO: Payment using cryptocurrency

- BANK_TRANSFER: Payment using bank transfer

Practical Applications of Enum in Java

Enum in Switch Statements

Using enum in Java with switch statements is one of the most common and effective applications. It provides type safety and readability that traditional constants cannot match.

// Using enum in switch statements
public enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class WeekdaySchedule {
    public static void main(String[] args) {
        Day today = Day.MONDAY;
        
        switch (today) {
            case MONDAY:
                System.out.println("Start of work week. Team meeting at 9 AM.");
                break;
            case TUESDAY:
            case WEDNESDAY:
            case THURSDAY:
                System.out.println("Regular work day.");
                break;
            case FRIDAY:
                System.out.println("Casual Friday. Weekly report due.");
                break;
            case SATURDAY:
            case SUNDAY:
                System.out.println("Weekend!");
                break;
            default:
                // This case will never execute since all enum values are covered
                System.out.println("Invalid day");
        }
    }
}

Output:

Start of work week. Team meeting at 9 AM.

Check out: Switch Case in Java

Singleton Pattern with Enum

One of the lesser-known applications of enum in Java is implementing the Singleton pattern. This approach is recommended by Joshua Bloch in "Effective Java" as it provides serialization safety and thread safety for free.

// Singleton pattern using enum in Java
public enum DatabaseConnection {
    INSTANCE;
    
    private Connection connection;
    
    // Private constructor
    private DatabaseConnection() {
        // Initialization code
        System.out.println("Creating database connection...");
        // In a real application, this would connect to an actual database
        connection = null; // Placeholder for actual connection
    }
    
    public Connection getConnection() {
        if (connection == null) {
            // Initialize connection if not already done
            // This is just a simplified example
            System.out.println("Connection initialized");
        }
        return connection;
    }
    
    public void executeQuery(String query) {
        System.out.println("Executing query: " + query);
        // Implementation details
    }
}

public class SingletonDemo {
    public static void main(String[] args) {
        // Access the singleton instance
        DatabaseConnection db = DatabaseConnection.INSTANCE;
        db.executeQuery("SELECT * FROM users");
        
        // Another reference to the same instance
        DatabaseConnection anotherDb = DatabaseConnection.INSTANCE;
        System.out.println("Same instance? " + (db == anotherDb));
    }
}

Output:

Creating database connection...

Executing query: SELECT * FROM users

Same instance? true

Also read: Java Classes and Objects

State Machine with Enum

Enums are perfect for implementing simple state machines in Java:

// State machine using enum in Java
public enum OrderStatus {
    NEW {
        @Override
        public OrderStatus nextState() {
            return PROCESSING;
        }
        
        @Override
        public boolean canTransitionTo(OrderStatus nextStatus) {
            return nextStatus == PROCESSING || nextStatus == CANCELED;
        }
    },
    
    PROCESSING {
        @Override
        public OrderStatus nextState() {
            return SHIPPED;
        }
        
        @Override
        public boolean canTransitionTo(OrderStatus nextStatus) {
            return nextStatus == SHIPPED || nextStatus == CANCELED;
        }
    },
    
    SHIPPED {
        @Override
        public OrderStatus nextState() {
            return DELIVERED;
        }
        
        @Override
        public boolean canTransitionTo(OrderStatus nextStatus) {
            return nextStatus == DELIVERED || nextStatus == RETURNED;
        }
    },
    
    DELIVERED {
        @Override
        public OrderStatus nextState() {
            return this; // Terminal state
        }
        
        @Override
        public boolean canTransitionTo(OrderStatus nextStatus) {
            return nextStatus == RETURNED;
        }
    },
    
    RETURNED {
        @Override
        public OrderStatus nextState() {
            return this; // Terminal state
        }
        
        @Override
        public boolean canTransitionTo(OrderStatus nextStatus) {
            return false; // Cannot transition from this state
        }
    },
    
    CANCELED {
        @Override
        public OrderStatus nextState() {
            return this; // Terminal state
        }
        
        @Override
        public boolean canTransitionTo(OrderStatus nextStatus) {
            return false; // Cannot transition from this state
        }
    };
    
    // Abstract methods to be implemented by each state
    public abstract OrderStatus nextState();
    public abstract boolean canTransitionTo(OrderStatus nextStatus);
}

public class OrderProcessingDemo {
    public static void main(String[] args) {
        OrderStatus status = OrderStatus.NEW;
        System.out.println("Initial status: " + status);
        
        // Simulate order processing flow
        while (status != status.nextState()) {
            status = status.nextState();
            System.out.println("Status updated to: " + status);
        }
    }
}

Output:

Initial status: NEW

Status updated to: PROCESSING

Status updated to: SHIPPED

Status updated to: DELIVERED

Conclusion

Enum in Java is more than just a way to define constants. It offers a type-safe and expressive approach to represent fixed sets of values. With support for fields, constructors, methods, and even interface implementation, enums make your code more readable and less error-prone. 

Java also provides built-in features like EnumSet and EnumMap for efficient enum handling. Whether you're learning the basics or applying advanced enum techniques, mastering this feature enhances your ability to write clean and maintainable Java code across various use cases.

FAQS

1. How are enums different from classes in Java?

Enums in Java are a special type of class with some restrictions:

  • Enums implicitly extend java.lang.Enum and cannot extend other classes
  • Enum constructors are implicitly private
  • Enum instances (constants) are created at compile time and cannot be instantiated using the new keyword
  • Enums are inherently serializable and thread-safe
  • Enums have some built-in methods like values() and valueOf()

2. Can Java enums extend classes?

No, Java enums cannot extend other classes because they implicitly extend java.lang.Enum. However, enums can implement interfaces, which allows you to define common behavior across different enum types.

3. Can we add methods to enum constants in Java?

Yes, you can add methods to individual enum constants in Java using anonymous class bodies. This allows each constant to have its own implementation of methods, as shown in the Operation and OrderStatus examples earlier in this article.

4. Are Java enums thread-safe?

Yes, Java enums are inherently thread-safe for basic operations because enum constants are created when the enum class is loaded, and they are effectively immutable. However, if you add mutable fields to your enum, you'll need to handle thread safety manually.

5. How to convert a String to an enum in Java?

To convert a String to an enum in Java, you can use the static valueOf() method that's automatically generated for every enum type:

Day day = Day.valueOf("MONDAY"); // Converts the string "MONDAY" to Day.MONDAY

Note that the string must exactly match the name of an enum constant (case-sensitive), or a IllegalArgumentException will be thrown.

6. How to iterate through all enum values in Java?

You can iterate through all enum values using the static values() method:

for (Day day : Day.values()) {
    System.out.println(day);
}

7. Can enums have constructors with parameters in Java?

Yes, enums can have constructors with parameters in Java. These parameters are specified when declaring the enum constants:

public enum Currency {
    USD("US Dollar", "$"),
    EUR("Euro", "€"),
    GBP("British Pound", "£"),
    JPY("Japanese Yen", "¥");
    
    private final String fullName;
    private final String symbol;
    
    Currency(String fullName, String symbol) {
        this.fullName = fullName;
        this.symbol = symbol;
    }
    
    public String getFullName() {
        return fullName;
    }
    
    public String getSymbol() {
        return symbol;
    }
}

8. Can we override enum methods in Java?

You can override methods for individual enum constants using anonymous class bodies, and you can override methods inherited from Object (like toString()). However, you cannot override the final methods inherited from Enum like name(), ordinal(), or valueOf().

9. How to use enums in JPA and Hibernate?

To use enums with JPA and Hibernate, you can use the @Enumerated annotation to specify how the enum should be stored in the database:

public class Employee {
    @Id
    private Long id;
    
    private String name;
    
    @Enumerated(EnumType.STRING) // Store enum as string (enum name)
    private EmployeeStatus status;
    
    // Alternative: store as ordinal (numeric position)
    // @Enumerated(EnumType.ORDINAL)
    // private EmployeeStatus status;
    
    // Getters and setters
}

public enum EmployeeStatus {
    ACTIVE, ON_LEAVE, TERMINATED
}

10. How to use enums in JSON serialization?

Most JSON libraries like Jackson and Gson handle Java enums naturally. By default, Jackson serializes enums as their name (string representation):

public class User {
    private String username;
    private Role role;
    
    // Getters and setters
}

public enum Role {
    ADMIN, USER, GUEST
}

// Using Jackson
ObjectMapper mapper = new ObjectMapper();
User user = new User();
user.setUsername("john");
user.setRole(Role.ADMIN);

String json = mapper.writeValueAsString(user);
// Output: {"username":"john","role":"ADMIN"}

11. What is the memory footprint of enums in Java?

Enums in Java are generally lightweight, but each enum constant is a singleton object, so they do consume some memory. For simple enums without fields or methods, the memory overhead is minimal. However, for complex enums with many fields and methods, the memory footprint can increase. In most cases, the benefits of using enums outweigh any memory concerns.

image

Take the Free Quiz on Java

Answer quick questions and assess your Java knowledge

right-top-arrow
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
advertise-arrow

Free Courses

Explore Our Free Software Tutorials

upGrad Learner Support

Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918068792934

Disclaimer

1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.

2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.