Joseph Haugh
University of New Mexico
// 0 = red, 1 = yellow, 2 = green
String lightMessage(int light) {
return switch (light) {
case 0 -> "STOP";
case 1 -> "SLOW DOWN";
case 2 -> "GO";
default -> "invalid!";
};
}
void main() {
IO.println(lightMessage(0)); // STOP
IO.println(lightMessage(2)); // GO
IO.println(lightMessage(9)); // invalid!
}
lightMessage(9) which is an invalid value accepted at runtimedefault case should be unreachable, yet the compiler forces us to write itString lightMessage(String light) {
return switch (light) {
case "red" -> "STOP";
case "yellow" -> "SLOW DOWN";
case "green" -> "GO";
default -> "invalid!";
};
}
void main() {
IO.println(lightMessage("red")); // STOP
IO.println(lightMessage("grren")); // invalid! typo, no compiler warning
IO.println(lightMessage("purple")); // invalid! any string accepted
}
default case is still neededint or String) to represent a restricted set of valuesint has billions of possible values; we only want threeString has infinitely many possible values; we only want threedefault requiredenum keyword, similar to classenum EnumName {
CONSTANT_ONE,
CONSTANT_TWO,
CONSTANT_THREE
}
ALL_CAPS by conventionEnumName.CONSTANT_ONEenum TrafficLight {
RED,
YELLOW,
GREEN
}
enum TrafficLight {
RED,
YELLOW,
GREEN
}
void main() {
TrafficLight light = TrafficLight.RED;
IO.println(light); // RED
light = TrafficLight.GREEN;
IO.println(light); // GREEN
}
TrafficLight.RED is TrafficLightIO.println prints the name of the constant automaticallyString lightMessage(TrafficLight light) {
return switch (light) {
case RED -> "STOP";
case YELLOW -> "SLOW DOWN";
case GREEN -> "GO";
};
}
default needed and if you add a new constant later, the compiler will flag any switch that does not handle itvoid main() {
TrafficLight light = TrafficLight.GREEN;
IO.println(lightMessage(light)); // GO
light = TrafficLight.RED;
IO.println(lightMessage(light)); // STOP
// lightMessage(9); COMPILE ERROR: int is not a TrafficLight
// lightMessage("red"); COMPILE ERROR: String is not a TrafficLight
// lightMessage(TrafficLight.PURPLE); COMPILE ERROR: no such constant
}
Another common use of enums: a fixed set of named values
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
this inside a method refers to the current constantenum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
boolean isWeekend() {
return switch (this) {
case SATURDAY, SUNDAY -> true;
case MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY -> false;
};
}
}
this is still exhaustive, no default neededvoid main() {
Day today = Day.WEDNESDAY;
IO.println(today.isWeekend()); // false
Day weekend = Day.SATURDAY;
IO.println(weekend.isWeekend()); // true
}
this, so the method behaves differently per constantShape enum where:
CIRCLE stores just a radiusRECTANGLE stores a width and a height// This does NOT compile in Java
enum Shape {
CIRCLE(5.0), // one value: radius
RECTANGLE(3.0, 4.0) // two values: width and height
}
CIRCLE and RECTANGLE would need different constructors, that is not allowedenum PizzaSize {
SMALL(8),
MEDIUM(12),
LARGE(16);
private final int diameterInches;
PizzaSize(int diameterInches) {
this.diameterInches = diameterInches;
}
public int getDiameter() { return diameterInches; }
}
diameterInches) with a different valuevoid main() {
PizzaSize size = PizzaSize.LARGE;
IO.println(size.getDiameter()); // 16
PizzaSize small = PizzaSize.SMALL;
IO.println(small.getDiameter()); // 8
}
Enums
this)ALL_CAPS for constant names by conventionWhen to Use Enums
| Situation | Enum? |
|---|---|
| Fixed set of named choices | Yes |
| All constants share the same data | Yes |
| Constants need different shapes of data | No |
| Arbitrary strings or numbers | No |