Enums
Sometimes a variable can take only a few values known in advance: days of the week, clothing sizes, order statuses. Keeping them as strings is risky — the compiler will not notice a typo. An enum (enum) defines such a set as a type of its own.
Declaring an enum
The values of an enum are called constants and are written in capital letters, separated by commas:
enum Size {
SMALL, MEDIUM, LARGE
}
void main() {
Size size = Size.MEDIUM;
IO.println(size);
}Output:
MEDIUMA variable of type Size can be assigned only one of the three constants — the compiler will not let anything else through.
Comparison and switch
Each constant exists in a single instance, so you can compare them with ==. Enums are convenient to handle in a switch:
enum Status {
NEW, PAID, SHIPPED
}
String describe(Status status) {
return switch (status) {
case NEW -> "Order created";
case PAID -> "Order paid";
case SHIPPED -> "Order shipped";
};
}
void main() {
Status status = Status.PAID;
IO.println(status == Status.PAID);
IO.println(describe(status));
}Output:
true
Order paidIn a case the constant name is written without the Status. prefix. If all constants are listed, a default branch is not needed.
All values
The values() method returns an array of all constants in declaration order, ordinal() returns a constant's number starting from zero, and name() returns its name as a string:
enum Size {
SMALL, MEDIUM, LARGE
}
void main() {
for (Size s : Size.values()) {
IO.println(s.ordinal() + ": " + s.name());
}
}Output:
0: SMALL
1: MEDIUM
2: LARGEIt is risky to rely on the ordinal() number when saving data, and for maps and sets of constants there are EnumMap and EnumSet — see the collections for enums lesson.
Fields, a constructor and methods
An enum is a class, so it can have fields, a constructor and methods. The constructor arguments are written in parentheses after each constant:
enum Coin {
CENT(1), NICKEL(5), DIME(10);
private final int cents;
Coin(int cents) {
this.cents = cents;
}
int cents() {
return cents;
}
}
void main() {
int total = 0;
for (Coin coin : Coin.values()) {
total += coin.cents();
}
IO.println("Total: " + total + " cents");
}Output:
Total: 16 centsIn this case a semicolon goes after the last constant.
From a string to a constant
The valueOf() method finds a constant by its name. This is handy when a value comes from a file or from user input:
enum Size {
SMALL, MEDIUM, LARGE
}
void main() {
Size size = Size.valueOf("LARGE");
IO.println(size.ordinal());
}Output:
2Common mistake
valueOf() looks for an exact, case-sensitive match. If there is no such constant, the program crashes with an exception:
enum Size {
SMALL, MEDIUM, LARGE
}
void main() {
Size size = Size.valueOf("large");
}Output:
Exception in thread "main" java.lang.IllegalArgumentException: No enum constant Main.Size.largeBring the string to the right form beforehand — Size.valueOf(text.toUpperCase()) — and be ready for wrong input.