[!NOTE] Often, an application has a variable that should only ever be one of three or four specific things. A user's role might be Admin, Moderator, or Guest. If you represent this as a
String, a developer might accidentally set a user's role to "Potato".
We solve this using Enums.
Defining an Enum
An enum is a special "class" that represents a group of constants (unchangeable variables).
// We declare all possible valid states globally
public enum Level {
LOW,
MEDIUM,
HIGH
}
Now, when you build a class, you don't use a String for the difficulty variable. You strictly type it to the Level enum!
public class GameSession {
// The type is 'Level', not 'String'!
Level currentDifficulty;
public GameSession() {
// You cannot assign "SUPER_HARD". The compiler restricts you to the 3 constants.
currentDifficulty = Level.MEDIUM;
}
}
Using Enums in Switch Statements
Enums shine the brightest when combined with a switch statement. It prevents developers from having to memorize random integer codes (like "Role 1 is Admin, Role 2 is Guest").
Level myVar = Level.HIGH;
switch(myVar) {
case LOW:
System.out.println("Low level");
break;
case MEDIUM:
System.out.println("Medium level");
break;
case HIGH:
System.out.println("High level executed!");
break;
}
Advanced Enums
Because Enums in Java are effectively fully-featured classes behind the scenes, you can actually add instance variables, constructors, and methods directly inside the Enum definition itself!
public enum Role {
// Define the enums and pass a parameter into their secret constructor!
ADMIN(99),
MODERATOR(50),
GUEST(1);
private int powerLevel;
// Private constructor used ONLY internally by the Enum creation above
private Role(int power) {
this.powerLevel = power;
}
public int getPowerLevel() {
return this.powerLevel;
}
}
// Somewhere else in code:
System.out.println(Role.ADMIN.getPowerLevel()); // Outputs 99!
Enums Prevent Invalid States
Enums are useful whenever a value must come from a fixed list. They make illegal values impossible at compile time. This is much safer than passing strings such as "admin", "Admin", or "ADMIN_USER" around the codebase.
Enum With Behavior
enum OrderStatus {
CREATED,
PAID,
SHIPPED,
CANCELLED;
boolean canCancel() {
return this == CREATED || this == PAID;
}
}
Enums can hold methods that explain rules related to their values. This keeps status-specific logic close to the status definition.
Using Enum Values Safely
OrderStatus status = OrderStatus.PAID;
if (status.canCancel()) {
System.out.println("Order can still be cancelled");
}
Common Mistakes
- Using strings for values that should be a controlled list.
- Comparing enum names as strings instead of comparing enum constants directly.
- Putting too many unrelated responsibilities inside an enum.
- Forgetting to handle all enum cases in important switch logic.
Mini Practice
Create an enum TicketPriority with LOW, MEDIUM, and HIGH. Add a method that returns the expected response time in hours for each priority.
Practice Lab: Ticket Priority Enum
Use enums to avoid random string states.
- Create enum
TicketPrioritywithLOW,MEDIUM, andHIGH. - Add a field for expected response hours.
- Add a constructor and getter.
- Use a switch to print escalation text for each priority.
- Try assigning an invalid priority and observe how the compiler protects you.
Goal: Use enums for controlled values plus related behavior.
Revision Checkpoint
- Enum: Fixed set of valid constants.
- Type safety: Prevents invalid string states.
- Switch: Enums pair well with clear branching.
- Fields and methods: Java enums can hold related behavior.
- Comparison: Compare enum constants directly.
Before the quiz: Replace one string status in your mind with an enum design.