Popular Searches
Popular Course Categories
Popular Courses

Working with Enum Methods and Enum Constructors

Working with Enum Methods and Enum Constructors

Wrapper Classes, Autoboxing, and Enumerations

Working with Enum Methods and Enum Constructors in Java

Course: Core Java Training

Topic: Working with Enum Methods and Enum Constructors

Course Link: Core Java Training Course

Demo Link: Register for a Course Demo

Academy Website: JustAcademy Official Website


1. Introduction to Enums in Java

An enum, short for enumeration, is a special Java type used to represent a fixed set of named constants. Enums make programs easier to understand, maintain, and validate because they restrict a variable to a predefined collection of values.

For example, an application may define days of the week, order statuses, payment methods, user roles, or traffic-light signals using enums.

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

public class EnumExample {
    public static void main(String[] args) {
        Day today = Day.MONDAY;
        System.out.println(today);
    }
}

Output:

MONDAY

Each enum constant is an instance of the enum type. Java enums can also contain fields, constructors, methods, and overridden behavior, making them more powerful than simple lists of constants.

2. Learning Objectives

  • Understand the purpose and structure of Java enums.
  • Learn commonly used built-in enum methods.
  • Use values(), valueOf(), name(), and ordinal().
  • Understand how enum constructors work.
  • Create enums with fields and custom methods.
  • Pass arguments to enum constructors.
  • Override methods for individual enum constants.
  • Apply enums in practical Java applications.

3. Declaring an Enum

An enum is declared using the enum keyword followed by its name and a list of constants. By convention, enum type names use PascalCase, while enum constants are usually written in uppercase letters separated by underscores.

enum PaymentStatus {
    PENDING,
    PROCESSING,
    COMPLETED,
    FAILED,
    CANCELLED
}

Each constant represents a predefined value of the PaymentStatus type.

public class PaymentDemo {
    public static void main(String[] args) {
        PaymentStatus status = PaymentStatus.COMPLETED;

        if (status == PaymentStatus.COMPLETED) {
            System.out.println("Payment successful");
        }
    }
}

Output:

Payment successful

Enum constants can be compared using == because each enum constant is a unique instance of its enum type.

4. Understanding Built-in Enum Methods

Java provides several useful methods for working with enum constants. Some are declared by the common java.lang.Enum superclass, while values() and valueOf(String) are generated for each enum type by the Java compiler.

Method Purpose Example
values() Returns an array of all enum constants in declaration order. Day.values()
valueOf(String) Returns the enum constant matching the exact specified name. Day.valueOf("MONDAY")
name() Returns the declared name of the enum constant. Day.MONDAY.name()
ordinal() Returns the zero-based position of the constant in its declaration. Day.MONDAY.ordinal()
toString() Returns a string representation; enums can override this method. Day.MONDAY.toString()
compareTo() Compares enum constants according to their declaration order. Day.MONDAY.compareTo(Day.FRIDAY)
getDeclaringClass() Returns the enum class that declared the constant. Day.MONDAY.getDeclaringClass()

5. Working with the values() Method

The values() method returns an array containing all constants of an enum in the order in which they are declared. It is especially useful for loops, menus, dropdown lists, and displaying available options.

enum Season {
    SPRING,
    SUMMER,
    AUTUMN,
    WINTER
}

public class ValuesMethodDemo {
    public static void main(String[] args) {
        for (Season season : Season.values()) {
            System.out.println(season);
        }
    }
}

Output:

SPRING
SUMMER
AUTUMN
WINTER

Key points:

  • The constants appear in declaration order.
  • The returned array can be used in enhanced for loops.
  • Changing the returned array does not change the enum's actual set of constants.
  • values() is compiler-generated for each enum type; it is not an ordinary method inherited from java.lang.Enum.

6. Working with the valueOf() Method

The valueOf(String) method converts a string containing an enum constant's exact declared name into the corresponding enum constant.

enum TrafficLight {
    RED,
    YELLOW,
    GREEN
}

public class ValueOfDemo {
    public static void main(String[] args) {
        TrafficLight light =
            TrafficLight.valueOf("GREEN");

        System.out.println(light);
    }
}

Output:

GREEN

The supplied name must match the enum constant exactly, including capitalization. If no matching constant exists, Java throws IllegalArgumentException. If the argument is null, it throws NullPointerException.

TrafficLight light = TrafficLight.valueOf("green");
// Throws IllegalArgumentException because the case differs.

For user input, validate or normalize the input before calling valueOf() when appropriate.

7. Understanding name() and toString()

The name() method returns the exact declared identifier of an enum constant. The toString() method normally returns the same text, but an enum can override toString() to provide a more user-friendly representation.

enum OrderStatus {
    PENDING,
    SHIPPED,
    DELIVERED;

    @Override
    public String toString() {
        return name().toLowerCase();
    }
}

public class EnumStringDemo {
    public static void main(String[] args) {
        OrderStatus status = OrderStatus.SHIPPED;

        System.out.println(status.name());
        System.out.println(status.toString());
    }
}

Output:

SHIPPED
shipped

Important distinction: name() always returns the declared constant name. toString() can be overridden, so it is useful for display text but should not be relied upon as a stable identifier when the representation may change.

8. Understanding the ordinal() Method

The ordinal() method returns the zero-based position of an enum constant in its declaration. The first constant has ordinal 0, the second has ordinal 1, and so on.

enum Priority {
    LOW,
    MEDIUM,
    HIGH,
    CRITICAL
}

public class OrdinalDemo {
    public static void main(String[] args) {
        System.out.println(Priority.LOW.ordinal());
        System.out.println(Priority.HIGH.ordinal());
    }
}

Output:

0
2

Although ordinal() can be useful for understanding declaration order, avoid using it as a persistent database value or business identifier. Reordering enum constants changes their ordinal values. For stable numeric codes, define an explicit field in the enum.

9. Understanding compareTo() for Enums

The compareTo() method compares enum constants according to their declaration order. It returns a negative number when the first constant precedes the second, zero when both constants are identical, and a positive number when the first follows the second.

enum Level {
    BEGINNER,
    INTERMEDIATE,
    ADVANCED
}

public class EnumCompareDemo {
    public static void main(String[] args) {
        System.out.println(
            Level.BEGINNER.compareTo(Level.ADVANCED)
        );

        System.out.println(
            Level.INTERMEDIATE.compareTo(Level.INTERMEDIATE)
        );
    }
}

Output:

-2
0

Enum ordering is based on declaration position. If business priority is independent of declaration order, define an explicit priority field and compare that field instead.

10. Introduction to Enum Constructors

Java enums can have constructors that initialize data associated with each constant. An enum constructor is similar to a class constructor, but it has important restrictions:

  • Its name must match the enum type name.
  • It cannot have a return type.
  • It cannot be invoked directly using new from application code.
  • It is implicitly private when no access modifier is specified, and enum constructors cannot be declared public or protected.
  • It is called as part of enum constant initialization.

Enum constructors are useful when each constant needs a code, description, category, fixed price, or other associated data.

11. Creating an Enum with a Constructor

The following example defines a Size enum whose constants pass a description to the constructor.

enum Size {
    SMALL("Small size"),
    MEDIUM("Medium size"),
    LARGE("Large size");

    private final String description;

    Size(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

public class EnumConstructorDemo {
    public static void main(String[] args) {
        Size size = Size.MEDIUM;

        System.out.println(size);
        System.out.println(size.getDescription());
    }
}

Output:

MEDIUM
Medium size

When Size.MEDIUM is initialized, the value "Medium size" is passed to the enum constructor. The constructor stores it in the description field, which can then be accessed through the getter method.

12. Enum Constructors with Multiple Parameters

An enum constructor can accept multiple parameters when each constant needs to store several pieces of information. Each constant must provide arguments that match the constructor's parameter types and order.

enum EmployeeRole {
    DEVELOPER("Software Developer", 50000),
    TESTER("Software Tester", 40000),
    MANAGER("Project Manager", 70000);

    private final String description;
    private final int baseSalary;

    EmployeeRole(String description, int baseSalary) {
        this.description = description;
        this.baseSalary = baseSalary;
    }

    public String getDescription() {
        return description;
    }

    public int getBaseSalary() {
        return baseSalary;
    }
}

public class EmployeeRoleDemo {
    public static void main(String[] args) {
        EmployeeRole role = EmployeeRole.DEVELOPER;

        System.out.println(role.getDescription());
        System.out.println(role.getBaseSalary());
    }
}

Output:

Software Developer
50000

In this example, each enum constant stores its own description and base salary. The fields are declared final so their values cannot be reassigned after initialization.

13. Defining Custom Methods Inside an Enum

Enums can contain instance methods, static methods, and overridden methods. Custom methods allow you to encapsulate behavior that belongs to the constants rather than placing all the logic in other classes.

enum Day {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY;

    public boolean isWeekend() {
        return this == SATURDAY || this == SUNDAY;
    }
}

public class WeekendDemo {
    public static void main(String[] args) {
        System.out.println(Day.MONDAY.isWeekend());
        System.out.println(Day.SUNDAY.isWeekend());
    }
}

Output:

false
true

The isWeekend() method checks which constant the current enum instance represents. The keyword this refers to the current enum constant.

14. Combining Enum Constructors and Methods

Enum constructors and methods can be combined to store data and provide behavior based on that data. The following example represents order statuses with descriptions and indicates whether each status is final.

enum OrderStatus {
    PENDING("Waiting for processing", false),
    PROCESSING("Order is being prepared", false),
    SHIPPED("Order has been shipped", false),
    DELIVERED("Order has been delivered", true),
    CANCELLED("Order has been cancelled", true);

    private final String description;
    private final boolean finalStatus;

    OrderStatus(String description, boolean finalStatus) {
        this.description = description;
        this.finalStatus = finalStatus;
    }

    public String getDescription() {
        return description;
    }

    public boolean isFinalStatus() {
        return finalStatus;
    }
}

public class OrderStatusDemo {
    public static void main(String[] args) {
        OrderStatus status = OrderStatus.DELIVERED;

        System.out.println(status.getDescription());
        System.out.println(status.isFinalStatus());
    }
}

Output:

Order has been delivered
true

This approach keeps status-related data and behavior together, which improves readability and makes the application easier to maintain.

15. Enum Constructors Are Not Called Directly

Enum constants are declared inside the enum itself. Java initializes them using the enum's constructor. Application code cannot create additional enum instances using the new keyword.

enum Color {
    RED,
    GREEN,
    BLUE
}

public class InvalidEnumExample {
    public static void main(String[] args) {
        // Invalid Java:
        // Color color = new Color();
    }
}

The commented statement is invalid because enum constructors cannot be invoked directly from application code. The available constants are Color.RED, Color.GREEN, and Color.BLUE.

16. Constructor Execution and Enum Constant Initialization

Each enum constant is initialized when its enum class is initialized. If a constant supplies constructor arguments, those arguments are passed to the enum constructor during initialization.

enum Level {
    LOW(1),
    MEDIUM(2),
    HIGH(3);

    private final int code;

    Level(int code) {
        this.code = code;
        System.out.println("Initializing code: " + code);
    }

    public int getCode() {
        return code;
    }
}

public class EnumInitializationDemo {
    public static void main(String[] args) {
        System.out.println(Level.HIGH.getCode());
    }
}

Output:

Initializing code: 1
Initializing code: 2
Initializing code: 3
3

The constants are initialized in declaration order when the enum class is initialized. The constructor output demonstrates that initialization happens for each declared constant, not only for the constant first referenced by the program.

17. Using Enum Methods in a switch Statement

Enums work well with switch statements because the compiler can check the possible enum constants. This is useful for implementing business rules such as discounts, access permissions, and order processing.

enum Membership {
    BASIC,
    SILVER,
    GOLD
}

public class MembershipDemo {
    public static void main(String[] args) {
        Membership membership = Membership.GOLD;

        switch (membership) {
            case BASIC:
                System.out.println("No discount");
                break;
            case SILVER:
                System.out.println("5% discount");
                break;
            case GOLD:
                System.out.println("15% discount");
                break;
        }
    }
}

Output:

15% discount

You can also place a method inside the enum to centralize the discount logic, preventing repeated switch statements throughout the application.

18. Overriding Methods for Individual Enum Constants

Java allows individual enum constants to provide their own implementation of a method. This is useful when each constant represents a different behavior.

enum Operation {
    ADD {
        public int calculate(int a, int b) {
            return a + b;
        }
    },
    SUBTRACT {
        public int calculate(int a, int b) {
            return a - b;
        }
    },
    MULTIPLY {
        public int calculate(int a, int b) {
            return a * b;
        }
    };

    public abstract int calculate(int a, int b);
}

public class OperationDemo {
    public static void main(String[] args) {
        System.out.println(Operation.ADD.calculate(10, 5));
        System.out.println(Operation.SUBTRACT.calculate(10, 5));
        System.out.println(Operation.MULTIPLY.calculate(10, 5));
    }
}

Output:

15
5
50

Each constant implements the abstract calculate() method differently. This technique can reduce lengthy conditional logic when behavior naturally belongs to each enum constant.

19. Practical Project: Product Shipping Calculator

This example uses an enum constructor to store shipping charges and a custom method to calculate the final cost of an order.

enum ShippingMethod {
    STANDARD("Standard Shipping", 50),
    EXPRESS("Express Shipping", 120),
    SAME_DAY("Same-Day Shipping", 200);

    private final String description;
    private final double charge;

    ShippingMethod(String description, double charge) {
        this.description = description;
        this.charge = charge;
    }

    public String getDescription() {
        return description;
    }

    public double getCharge() {
        return charge;
    }

    public double calculateTotal(double productPrice) {
        return productPrice + charge;
    }
}

public class ShippingCalculator {
    public static void main(String[] args) {
        double productPrice = 1000;

        ShippingMethod method = ShippingMethod.EXPRESS;

        System.out.println(method.getDescription());
        System.out.println(method.getCharge());
        System.out.println(method.calculateTotal(productPrice));
    }
}

Output:

Express Shipping
120.0
1120.0

The enum stores the shipping description and charge, while its method calculates the total amount. For real financial applications, use BigDecimal or integer minor currency units instead of floating-point arithmetic for monetary calculations.

20. Common Errors and Troubleshooting

Error or Mistake Reason Solution
Missing semicolon after enum constants when adding members Fields, constructors, or methods follow the constants without the required separator. Place a semicolon after the constant list when additional members follow.
Incorrect constructor arguments A constant's arguments do not match the constructor signature. Check argument count, order, and data types.
Declaring a public enum constructor Enum constructors cannot be public or protected. Use a constructor without an access modifier or declare it private.
Trying to instantiate an enum with new Enum instances are created as declared constants. Use an existing constant such as Color.RED.
Calling valueOf() with an incorrect name The string does not match a constant's declared name exactly. Validate the input and handle IllegalArgumentException.
Using ordinal() as a permanent code Reordering constants changes their ordinal values. Store an explicit code in a field.
Overriding toString() and using it as a persistent identifier The display representation can change. Use name() when the exact declared name is required.
Attempting to change a final field Final fields cannot be reassigned after initialization. Initialize the field in the constructor and use getters.

21. Best Practices for Enum Methods and Constructors

  • Use enums when a variable should represent one of a fixed set of values.
  • Give enum constants clear, descriptive names.
  • Use constructors to initialize constant-specific data.
  • Prefer private final fields with public getter methods for immutable enum data.
  • Use custom methods to keep enum-related behavior inside the enum.
  • Use values() to iterate over all constants.
  • Handle invalid input when converting strings with valueOf().
  • Use name() for the exact declared name and toString() for a potentially customized representation.
  • Avoid using ordinal() as a database identifier or permanent business code.
  • Use explicit fields for stable codes, priorities, or descriptions.
  • Keep enum constructors simple and avoid complex side effects during initialization.
  • Use constant-specific method implementations when each enum constant needs different behavior.

22. Practice Exercises

  1. Create an enum named Month containing all twelve months. Use values() to print every month.
  2. Create a Direction enum with a method that returns whether the direction is vertical or horizontal.
  3. Create a CourseLevel enum with a constructor that stores a description and a numeric code.
  4. Write a program that converts a string into an enum constant using valueOf() and handles invalid input.
  5. Create a PaymentMethod enum with constants for cash, card, and online payments. Store a readable description for each constant.
  6. Create an enum with a method that returns a different message for each constant.
  7. Build a simple order-status program that uses an enum constructor, getters, and a custom method to determine whether an order is complete.

23. Interview Questions and Answers

Q1. What is an enum in Java?

Answer: An enum is a special Java type that represents a fixed set of named constants.

Q2. Can an enum contain constructors?

Answer: Yes. An enum can have constructors that initialize fields associated with each constant. These constructors cannot be invoked directly using new.

Q3. Can an enum constructor be public?

Answer: No. Enum constructors cannot be declared public or protected. They are private implicitly when no access modifier is specified, or they can be declared private explicitly.

Q4. What is the purpose of values()?

Answer: It returns an array of all constants in declaration order. The compiler provides this method for each enum type.

Q5. What is the purpose of valueOf()?

Answer: It returns the enum constant whose declared name exactly matches the supplied string. It throws an exception if the name is invalid.

Q6. What is the difference between name() and toString()?

Answer: name() returns the exact declared constant name and cannot be overridden. toString() can be overridden to provide a different representation.

Q7. What does ordinal() return?

Answer: It returns the zero-based declaration position of the enum constant.

Q8. Can enums have fields and methods?

Answer: Yes. Enums can define instance fields, constructors, instance methods, static methods, and overridden methods.

Q9. Why should ordinal() not be used as a permanent database identifier?

Answer: Its value depends on declaration order and can change when constants are reordered. An explicit code field is more stable.

Q10. Can different enum constants implement the same method differently?

Answer: Yes. An enum can declare an abstract method and provide a separate implementation in each constant's class body.

Q11. What happens if valueOf() receives an invalid constant name?

Answer: It throws IllegalArgumentException. Passing a null name throws NullPointerException.

Q12. Why use a constructor inside an enum?

Answer: It allows each constant to store its own data, such as a description, code, price, or priority.

24. Quick Revision Checklist

  • An enum represents a fixed set of named constants.
  • Enum constants are instances of their enum type.
  • values() returns all constants in declaration order.
  • valueOf() finds a constant using its exact declared name.
  • name() returns the exact constant identifier.
  • toString() can provide a customized string representation.
  • ordinal() returns a zero-based declaration position.
  • Enums can contain fields, constructors, and methods.
  • Enum constructors cannot be called directly using new.
  • Enum constructors cannot be public or protected.
  • Use explicit fields for stable business codes instead of ordinals.
  • Constant-specific class bodies can provide different implementations of a method.

25. Conclusion

Enum methods and constructors help developers create type-safe, readable, and maintainable Java programs. Built-in methods such as values(), valueOf(), name(), and ordinal() make it easy to inspect and work with enum constants. Constructors allow each constant to hold its own data, while custom methods define behavior related to the enum.

By combining enum constants, fields, constructors, and methods, you can represent real-world concepts such as order statuses, payment methods, employee roles, shipping options, and application settings in a structured way.

Further Learning Resources

Previous Next
whatsapp