Skip to main content

Enum Constructors and Fields

The true power of an enum in Java comes from the fact that it is a class.

Because an enum is a class, it can have fields (instance variables), methods, and even constructors. This allows you to attach specific data and behavior to each individual enum constant.


Adding Fields and Constructors

If you want to associate data with an enum constant, you must do three things:

  1. Define the instance variables (fields) inside the enum.
  2. Create a constructor that takes the data as arguments and assigns it to the fields.
  3. Pass the arguments directly to the constants at the top of the enum using parentheses.

The Rules of Enum Constructors

  • An enum constructor cannot be public or protected. It must be private (or package-private by default).
  • You cannot manually invoke the constructor using the new keyword. The JVM automatically invokes the constructor for each constant when the enum class is loaded into memory.

Example: Attaching Data to Enums

Let's imagine we are building a coffee shop application. We want an enum for the sizes of coffee, but we also want to attach the exact volume (in ounces) to each size.

enum CoffeeSize {
// 1. Pass the arguments to the constants
SMALL(8),
MEDIUM(12),
LARGE(16),
VENTI(20);

// 2. Define the instance variable
private final int ounces;

// 3. Create a private constructor
private CoffeeSize(int ounces) {
this.ounces = ounces;
}

// 4. Create a public getter method
public int getOunces() {
return this.ounces;
}
}

public class LabEnumAdvanced1 {

public static void main(String[] args) {
CoffeeSize myOrder = CoffeeSize.VENTI;

System.out.println("You ordered a " + myOrder + " coffee.");

// Calling the getter method on the enum constant!
System.out.println("That is " + myOrder.getOunces() + " ounces of coffee.");
}
}

Output:

You ordered a VENTI coffee.
That is 20 ounces of coffee.

Multiple Fields in an Enum

You are not restricted to just one piece of data. You can attach as many fields as you need.

enum TrafficLight {
// Constants with two arguments: color code and action
RED("#FF0000", "STOP"),
YELLOW("#FFFF00", "SLOW DOWN"),
GREEN("#00FF00", "GO");

private final String hexCode;
private final String action;

// Constructor taking two parameters
private TrafficLight(String hexCode, String action) {
this.hexCode = hexCode;
this.action = action;
}

public String getHexCode() {
return hexCode;
}

public String getAction() {
return action;
}
}

public class LabEnumAdvanced2 {

public static void main(String[] args) {
for (TrafficLight light : TrafficLight.values()) {
System.out.println("Light: " + light);
System.out.println(" - Code: " + light.getHexCode());
System.out.println(" - Action: " + light.getAction());
}
}
}

[!TIP] Notice how we made the instance variables private final. While it is not strictly required to make them final, it is highly recommended. Enum constants represent fixed values, so the data attached to them should also be immutable (unchangeable).