Enum Methods and Enums in Switch
Every enum gets a set of methods for free: some the compiler writes for you (values() and valueOf()), and some inherited from java.lang.Enum (name(), ordinal(), compareTo()). They let you loop over all constants, turn user input into a constant, and sort constants in declaration order. Enums also fit switch perfectly, including exhaustive switch expressions that need no default.
The Built-In Methods
import java.util.Arrays;
public class Orders {
enum Status { PLACED, PACKED, SHIPPED, DELIVERED }
public static void main(String[] args) {
System.out.println(Arrays.toString(Status.values()));
Status s = Status.valueOf("SHIPPED");
System.out.println(s.name() + " is step " + (s.ordinal() + 1));
System.out.println(s.compareTo(Status.DELIVERED));
try {
Status.valueOf("shipped");
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
Status fromUser = Status.valueOf(" packed ".strip().toUpperCase());
System.out.println("Parsed: " + fromUser);
}
}[PLACED, PACKED, SHIPPED, DELIVERED]
SHIPPED is step 3
-1
No enum constant Orders.Status.shipped
Parsed: PACKEDHow it works
values()returns a new array of all constants in declaration order.valueOf("SHIPPED")finds the constant with that exact name.name()returns the constant's name;ordinal()its position, counting from 0.compareTocompares by declaration order:SHIPPEDcomes beforeDELIVERED, so the result is negative.valueOfis case-sensitive and throwsIllegalArgumentExceptionfor unknown names. Normalize user input withstrip()andtoUpperCase()first.
Method Reference
| Method | Comes from | Notes |
|---|---|---|
static E[] values() | Generated by the compiler | A new array on each call |
static E valueOf(String name) | Generated by the compiler | Exact, case-sensitive match |
String name() | java.lang.Enum | final; always the declared name |
String toString() | java.lang.Enum | Returns name() by default; can be overridden for display |
int ordinal() | java.lang.Enum | Position from 0; changes if constants are reordered |
int compareTo(E other) | java.lang.Enum | Order of declaration |
Class<E> getDeclaringClass() | java.lang.Enum | The enum type |
Enums in switch
public class Tracking {
enum Status { PLACED, PACKED, SHIPPED, DELIVERED }
static String message(Status s) {
return switch (s) {
case PLACED -> "We have your order";
case PACKED -> "Packed and ready";
case SHIPPED -> "On the way";
case DELIVERED -> "Delivered. Enjoy!";
};
}
public static void main(String[] args) {
for (Status s : Status.values()) {
System.out.println(s + ": " + message(s));
}
}
}PLACED: We have your order
PACKED: Packed and ready
SHIPPED: On the way
DELIVERED: Delivered. Enjoy!Inside the case labels you write PLACED, not Status.PLACED. Because the switch expression lists every constant, it's exhaustive and needs no default. If someone adds RETURNED later, this switch stops compiling until it's handled, which is exactly what you want.
Common Mistakes
valueOf on raw user input. Normalize the case and spaces, and catch IllegalArgumentException.
Writing case Status.PLACED. Older Java required the bare constant name; it's always clearest.
Relying on toString() for parsing. If toString() is overridden for display, valueOf still needs name().
Under the Hood
javap -p shows what the compiler turns an enum into:
final class Orders$Status extends java.lang.Enum<Orders$Status> {
public static final Orders$Status PLACED;
public static final Orders$Status PACKED;
public static final Orders$Status SHIPPED;
public static final Orders$Status DELIVERED;
private static final Orders$Status[] $VALUES;
public static Orders$Status[] values();
public static Orders$Status valueOf(java.lang.String);
private Orders$Status();
private static Orders$Status[] $values();
static {};
}An enum is a final class extending Enum, each constant is a public static final field created in the static block, the constructor is private, and values() returns a copy of the hidden $VALUES array. That's also why new Status() fails with enum classes may not be instantiated.
Interview Corner
What is the difference between name() and toString() for an enum?
name() is final and always returns the constant's exact declared name. toString() returns the same by default but can be overridden, for example to return a display label. Use name() when the exact identifier matters, such as for valueOf or storage.
What does valueOf() do with an invalid name?
It throws IllegalArgumentException with a message like "No enum constant Orders.Status.shipped". The match is exact and case-sensitive; passing null throws NullPointerException.
Practice
- Easy: For an enum
Planetwith five constants, print each constant's name and ordinal usingvalues(). - Harder: Write
static Status parse(String text)that accepts any case and surrounding spaces, and returnsPLACEDfor unknown text instead of throwing.
Key Takeaways
Was this tutorial helpful?