Java Enum – A Complete Guide to Enumeration in Java with Examples

Enums (short for "enumerations") are a powerful feature in Java that allow you to define a fixed set of constants. This special data type is ideal for representing a restricted set of values that don‘t change at runtime, such as days of the week, chess pieces, card suits, and so on.

Proper use of enums can make your code more expressive, type-safe, and maintainable. In this in-depth guide, we‘ll cover everything you need to know about Java enums, from the basics of how to declare and use them, to advanced features and best practices. We‘ll wrap up with some interesting real-world examples. Let‘s get started!

Declaring and Using Basic Enums

The syntax for declaring an enum is similar to a class. Use the enum keyword followed by the name (which should be a singular noun), and list the constant values (in ALL_CAPS by convention):

public enum DaysOfWeek {
    SUNDAY, 
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY
}

Each enum constant is actually an instance of the enum class. You can declare variables of the enum type and assign them enum values:

DaysOfWeek today = DaysOfWeek.WEDNESDAY;

You can print an enum value directly:

System.out.println(today); // prints "WEDNESDAY"

Enum values can be used in switch statements:

switch (today) {
    case SATURDAY:
    case SUNDAY:   
        System.out.println("It‘s the weekend!");
        break;
    default:
        System.out.println("It‘s a weekday.");
        break;
}

To get an array of all enum values, use the implicit values() method:

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

The ordinal() method returns the zero-based position of an enum constant:

int ordinal = DaysOfWeek.THURSDAY.ordinal(); // 4

However, avoid depending on ordinal values in your code, as they may change if the enum constants are reordered.

Adding Constructors, Methods and Fields

Enums can have constructors, methods, and fields just like regular classes. This allows you to associate additional data and behavior with each enum constant.

For example, let‘s associate a description with each day of the week:

public enum DaysOfWeek {
    SUNDAY("Off"), 
    MONDAY("Working"),
    TUESDAY("Working"),
    WEDNESDAY("Working"),
    THURSDAY("Working"),
    FRIDAY("Working"),
    SATURDAY("Off");

    private final String description;

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

    public String getDescription() {
        return description;
    } 
}

Now we can access the description like this:

String desc = DaysOfWeek.SATURDAY.getDescription(); // "Off"

Methods in an enum are just like regular class methods and can perform any necessary logic:

public boolean isWorkingDay() {
    return !this.equals(SATURDAY) && !this.equals(SUNDAY);
}

We can invoke this method on an enum value:

boolean working = DaysOfWeek.WEDNESDAY.isWorkingDay(); // true

Constants can override methods:

SUNDAY {
    @Override
    public boolean isWorkingDay() {
        return false; 
    }
},
SATURDAY {
    @Override
    public boolean isWorkingDay() {
        return false;
    }  
},

Enums can even implement interfaces:

public interface Describable {
    String getDescription();
}

public enum DaysOfWeek implements Describable {
    //...
}

Real-World Examples

Enums are used extensively in real-world Java code. Here are a few examples:

The java.time.DayOfWeek and java.time.Month enums represent days and months:

DayOfWeek dayOfWeek = DayOfWeek.MONDAY;
Month month = Month.APRIL;

The Locale class uses enums for language and country codes:

Locale locale = Locale.forLanguageTag("en-US");
Locale.IsoCountryCode country = locale.getCountry();
Locale.LanguageCode language = locale.getLanguage();

The Java Persistence API (JPA) supports mapping enums to database values:

@Entity
public class Employee {
    @Enumerated(EnumType.STRING)
    private Department department;

    public enum Department {
        SALES, ENGINEERING, MARKETING
    }    
}

The RoundingMode enum controls rounding behavior in the BigDecimal class:

BigDecimal value = new BigDecimal("5.5");
value = value.setScale(0, RoundingMode.UP); // 6

Under the Hood

It‘s helpful to understand how enums work behind the scenes. The Java compiler actually transforms an enum into a class that extends java.lang.Enum. The enum constants become public static final instances of this class.

For example, the DaysOfWeek enum we defined earlier gets translated to something like this:

public final class DaysOfWeek extends Enum<DaysOfWeek> {
    public static final DaysOfWeek SUNDAY = new DaysOfWeek("Off");
    public static final DaysOfWeek MONDAY = new DaysOfWeek("Working"); 
    //...

    private DaysOfWeek(String description) {
        super("DaysOfWeek", ordinal());
        this.description = description;
    }
}

This is why enums implicitly have methods like values(), ordinal() and name() – they are inherited from the Enum base class.

Enums vs Constants

You may be wondering how enums differ from the old-school approach of using a bunch of static final constants. While both can represent fixed sets of values, enums offer several advantages:

  1. Enums are actual types, allowing the compiler to perform type checking. With constants, any int value could be passed in and the error wouldn‘t be caught until runtime.

  2. Enums can be used in switch statements.

  3. Enums can have methods and fields for associating data and behavior with the values.

  4. Enum values are proper instances that can be used polymorphically.

  5. Enums are more expressive and readable (assuming good naming!).

So in general, prefer enums over constants. However, if you need a very large number of values or require integer constants specifically, plain constants may be appropriate.

Best Practices and Caveats

Here are some tips and gotchas to keep in mind when working with enums in Java:

  • Name enums and constants appropriately. Enum names are usually singular nouns, while constants are ALL_CAPS with underscores.

  • Declare the enum at the top level scope or inside a class, not inside a method.

  • Avoid depending on the implicit ordinal values as they may change.

  • Prefer putting switch cases for an enum inside the enum class itself.

  • Consider implementing interfaces on enums for more flexible polymorphic behavior.

  • Remember that enums are effectively global singletons, so be careful about holding onto state.

  • While enum constructors can‘t be directly invoked, they are still invoked once for each constant during class initialization.

  • If serializing an enum, ensure the order and names of constants don‘t change to maintain compatibility.

Enum Utilities and APIs

The JDK provides a few handy utilities and APIs for working with enums:

  • java.util.EnumSet: A specialized, high-performance Set implementation for enums. Internally uses a bit vector for efficient storage and manipulation.

  • java.util.EnumMap: A specialized high-performance Map implementation with enum keys. Uses an array for efficient storage.

  • The javax.lang.model.util.Elements interface, part of the annotation processing API, provides utilities for working with enum types.

Conclusion

We‘ve covered a lot of ground in this guide to Java enums! You should now have a solid grasp of what enums are, why they are useful, how to declare and use them, and some advanced techniques and best practices.

To recap, enums provide a type-safe and expressive way to represent a fixed set of constants. They can have constructors, methods, and fields to associate data and behavior with the enum values. Enums are used extensively in the JDK and many third party libraries and frameworks.

When working with enums, remember to name them well, avoid relying on ordinals, and consider implementing relevant interfaces. The EnumSet and EnumMap classes offer efficient specialized collection implementations to use with enums.

I hope you‘ve found this guide informative and useful! Let me know in the comments if you have any other enum-related tips or questions. Happy coding!

Similar Posts