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
}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 errorUsing 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");
}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; }
}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 52Methods 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.0Useful 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...
}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.LARGEIf the text doesn’t match exactly, it throws IllegalArgumentException.