java-enums-enumerados-avanzados

Enums in Java: values, attributes, and methods

  • 3 min

A enum is a type that represents a closed set of named values.

Imagine you are programming an application for a t-shirt store. You need to store the size.

What data type do you use?

  • A String? product.size = "Large"; (Danger: Someone could write “Largge” or “Big”).
  • An int? product.size = 3; (Danger: What does 3 mean? L, XL? What if someone enters 99?).

To solve this, to represent a fixed and limited set of options, we have Enumerations (Enums).

The basic enum

The basic syntax is very simple. We define a new data type with the allowed options. By convention, constants are in UPPERCASE.

public enum Size {
    SMALL, MEDIUM, LARGE, EXTRA_LARGE
}
Copied!

Now we have Type Safety. The compiler won’t let us put in garbage.

Size mySize = Size.MEDIUM;

// Size s = "MEDIUM"; // Compilation error
// Size s = 2;        // Compilation error
Copied!

Using enums in switch

Enums are the best friends of switch. The code reads almost like natural language.

switch (mySize) {
    case SMALL -> System.out.println("Size S");
    case MEDIUM -> System.out.println("Size M");
    case LARGE, EXTRA_LARGE -> System.out.println("Size L/XL");
}
Copied!

Advanced enums: attributes and constructors

As we said, in Java an enum is actually a special Class (which inherits from java.lang.Enum). This means they can have attributes, constructors, and methods.

Let’s continue with sizes. A size is not just a name (“LARGE”), it often also has an abbreviation (“L”) and a width in centimeters (52). We can store that information within the Enum itself.

public enum Size {
    // 1. Define the constants, passing data to the constructor
    SMALL("S", 48),
    MEDIUM("M", 50),
    LARGE("L", 52),
    EXTRA_LARGE("XL", 54); // The semicolon separates constants from the rest of the code

    // 2. Attributes (final, because enums are constants)
    private final String abbreviation;
    private final int widthCm;

    // 3. Constructor (Mandatorily Private)
    // Only called internally when creating the constants above
    private Size(String abbreviation, int width) {
        this.abbreviation = abbreviation;
        this.widthCm = width;
    }

    // 4. Getters (to access the data)
    public String getAbbreviation() { return abbreviation; }
    public int getWidthCm() { return widthCm; }
}
Copied!

Notice the power of this. Now the data and its metadata go together.

Size s = Size.LARGE;
System.out.println(s.getAbbreviation()); // Prints "L"
System.out.println(s.getWidthCm());     // Prints 52
Copied!

Methods in enums

We can add business logic directly in the Enum.

public enum Operation {
    ADD, SUBTRACT, MULTIPLY, DIVIDE;

    public double calculate(double a, double b) {
        return switch (this) { // 'this' is the current constant (ADD, SUBTRACT...)
            case ADD -> a + b;
            case SUBTRACT -> a - b;
            case MULTIPLY -> a * b;
            case DIVIDE -> a / b;
        };
    }
}

// Usage:
double res = Operation.ADD.calculate(10, 20); // 30.0
Copied!

Useful methods: values() and valueOf()

Java gives a couple of static methods to all Enums that are very useful for iterating over them.

  • values(): Returns an Array with all the constants. Ideal for populating a ComboBox in a graphical interface.
for (Size s : Size.values()) {
    System.out.println(s); // Prints SMALL, MEDIUM...
}
Copied!
  • valueOf("STRING"): Converts text to Enum. Very useful when you read data from a file or database.
String text = "LARGE";
Size s = Size.valueOf(text); // Converts to Size.LARGE
Copied!

If the text doesn’t match exactly, it throws IllegalArgumentException.