Sunday, 24 August 2025

ENUM

Enum

Enums were introduced in Java 5 (JDK 1.5) as a way to define a collection of named constants in a type-safe manner. Unlike enums in older languages (like C or C++), Java enums are far more powerful since they are implemented using class concepts and can contain constructors, methods, and variables.

What is an Enum?

  • Enum is a special data type used to define a group of named constants.
  • Each enum constant is implicitly:

    • public, static, and final.
  • Enums make the code readable, maintainable, and less error-prone compared to using int or String constants.
Example :

enum Month {
    JAN, FEB, MAR, DEC;
}

Internal Implementation of Enum

  • Internally, an enum is implemented as a class.
  • Every enum constant is a reference variable that points to its own enum object.
  • You can think of enums as a fixed set of static final objects.

Enum Declaration and Usage :

enum Month{
    JAN, FEB, MAR, DEC; // semicolon at the end is optional if no extra members
}

class Test {
    public static void main(String[] args) {
        Month mon = Month.FEB;
        System.out.println(mon);
    }
}
Output:

FEB
👉 Note: Since enum constants are implicitly static, we can access them using EnumName.CONSTANT.

Enum with Switch Statement :

Before Java 5, switch allowed only byte, short, char, int (and their wrappers). From Java 5 onwards, enum types can also be used in a switch.

Example:

enum PaymentStatus {
    PENDING, PROCESSING, SUCCESS, FAILED;
}

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

        switch (status) {
            case PENDING:
                System.out.println("Payment is pending. Please wait...");
                break;
            case PROCESSING:
                System.out.println("Payment is being processed. Do not refresh the page.");
                break;
            case SUCCESS:
                System.out.println("Payment successful! Thank you for your purchase.");
                break;
            case FAILED:
                System.out.println("Payment failed. Please try again.");
                break;
            default:
                System.out.println("Unknown payment status.");
        }
    }
}
Output :

Payment is being processed. Do not refresh the page.
👉 Every case label must be a valid enum constant, otherwise you’ll get a compile-time error.

Enum and Inheritance

  • Every enum in Java is implicitly a child of java.lang.Enum.
  • Hence, enums cannot extend other classes.
  • Enums are implicitly final, so they cannot be extended.
  • But enums can implement interfaces.

Useful Enum Methods

  1. values() returns all constants as an array.
  2. ordinal() returns the index (zero-based position) of the constant.
  3. valueOf(String name) returns the enum constant with the specified name 

values():

  • Returns an array containing all the constants of the enum, in the order they were declared.
  • Automatically added by the compiler for every enum type.
  • Return type: EnumType[]
📌 Syntax :
    
  public static EnumType[] values()

ordinal():

  • Returns the position (zero-based index) of the enum constant in its declaration.
  • Return type: int
  • Use case: Helpful when you need the position/order of the enum constant (e.g., for iteration or sorting).

valueOf(String name)

  • Returns the enum constant with the specified name.
  • The name must exactly match the declared constant (case-sensitive).
  • Return type: EnumType
  • Use case: Useful for converting a string into the corresponding enum constant.
📌 Syntax :
    
  public static EnumType valueOf(String name)

📌Eample :

  enum Day {
    MONDAY, TUESDAY, WEDNESDAY;
}

class Test {
    public static void main(String[] args) {
        // Using the compiler-generated method
        Day d1 = Day.valueOf("MONDAY");

        // Using Enum.valueOf (generic)
        Day d2 = Enum.valueOf(Day.class, "TUESDAY");

        System.out.println(d1); 
        System.out.println(d2); 
    }
}

Output :

MONDAY
TUESDAY

⚠️ Important Note:

  • If the string doesn’t match exactly, it throws IllegalArgumentException.
  • "monday" (lowercase) would fail because enum names are case-sensitive.

📌 Important Notes

  • The name must match the enum constant exactly (case-sensitive).
  • If the string doesn’t match any constant, it throws IllegalArgumentException.
  • null input throws NullPointerException.

✅ So yes, valueOf(String name) is always available for enums in Java, either via the compiler-generated method or the generic Enum.valueOf() method.

📌Note : 

  • ordinal() is defined in the java.lang.Enum class.
  • valueOf(String) is also defined in the Enum class. 
  • values() is not defined in Enum; instead, it is a synthetic method automatically generated by the compiler for each enum type. That’s why you won’t find it in the JDK source of Enum.


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

class Test {
    public static void main(String[] args) {
        Day[] days = Day.values();
        for (Day d : days) {
            System.out.println(d + " ---> " + d.ordinal());
        }
    }
}
Output :

MONDAY ---> 0
TUESDAY ---> 1
WEDNESDAY ---> 2
THURSDAY ---> 3
FRIDAY ---> 4
SATURDAY ---> 5
SUNDAY ---> 6

✅ Key Differences :

Featureordinal()valueOf(String name)values()
PurposeReturns index (position) of constantReturns enum constant by its nameReturns an array of all enum constants
Return TypeintEnum type itselfEnum array (EnumType[])
InputNo input (called on enum constant)Takes String argumentNo input (called on enum type)
Example UsageDay.MONDAY.ordinal()0Day.valueOf("MONDAY")Day.MONDAYDay.values()[MONDAY, TUESDAY, …]
RiskChanges if enum order is modifiedThrows IllegalArgumentException if not foundNone (safe, but array order depends on enum order)

Enum with Constructors and Fields

Each enum constant is actually an object, and constructors are executed at class loading time.

enum UserRole {
    ADMIN(5), MODERATOR(3), CUSTOMER(1), GUEST;

    private int accessLevel;

    // parameterized constructor
    UserRole(int accessLevel) {
        this.accessLevel = accessLevel;
    }

    // default constructor (for GUEST)
    UserRole() {
        this.accessLevel = 0;
    }

    public int getAccessLevel() {
        return accessLevel;
    }
}

class Test {
    public static void main(String[] args) {
        for (UserRole role : UserRole.values()) {
            System.out.println(role + " has access level " + role.getAccessLevel());
        }
    }
}
Output :

ADMIN has access level 5
MODERATOR has access level 3
CUSTOMER has access level 1
GUEST has access level 0
Note :👉 You cannot create enum objects manually (new UserRole() is not allowed). They are created internally at load time.
         👉 This way, each UserRole constant represents a real application role with an access level (like permissions in a system).

Enum with Methods

Enums can override methods just like classes.

Example:

enum NotificationType {
    EMAIL {
        @Override
        public void send() {
            System.out.println("Sending Email Notification...");
        }
    },
    SMS {
        @Override
        public void send() {
            System.out.println("Sending SMS Notification...");
        }
    },
    PUSH; // uses default implementation
    // default behavior
    public void send() {
        System.out.println("Sending Push Notification...");
    }
}

class Test {
    public static void main(String[] args) {
        for (NotificationType type : NotificationType.values()) {
            type.send();
        }
    }
}
Output :

Sending Email Notification...
Sending SMS Notification...
Sending Push Notification...

Static Import with Enum

You can use static imports to avoid qualifying enum constants.

package pack1;
public enum Fish {
    STAR, GUPPY;
}
package pack2;
import static pack1.Fish.*;

class A {
    public static void main(String[] args) {
        System.out.println(STAR);
        System.out.println(GUPPY);
    }
}

Valid imports:

  1. import static pack1.Fish.*;

  2. import static pack1.Fish.STAR;

Invalid imports:

  1. import pack1.*;

  2. import pack1.Fish;

📝Key Points (Latest Java Versions ✅)

  • Enums are type-safe constants.
  • They can have fields, methods, and constructors.
  • They cannot extend other classes, but can implement interfaces.
  • Enums are thread-safe since all constants are created at class loading.
  • From Java 5 onwards, enums can be used in switch.
  • Useful methods: values(), ordinal(), name(), compareTo().
  • They work seamlessly with Collections, Generics, and Streams (Java 8+).


No comments:

Post a Comment

Java Development Kit (JDK) and Java Runtime Environment (JRE)

                  Java Development Kit (JDK) and Java Runtime Environment (JRE)  To download and install the Java Development Kit (  JDK ) ...