Enums and Records
Brew Bar's sizes were stored as strings, and one day an order arrived for size "Lrg". Its order lines were ordinary classes with forty lines of constructor, getters and equals code. Two modern Java features fix both problems: enums for a fixed set of choices and records for plain data.
The rule
Fixed choices become an enum; plain data becomes a record.
An enum is a type with a closed list of named values. Nothing else can ever be a Size, so typos cannot compile:
public enum Size {
SMALL(250), MEDIUM(300), LARGE(350);
private final int priceCents;
Size(int priceCents) { this.priceCents = priceCents; }
public int priceCents() { return priceCents; }
}Enums can carry fields and methods, as here. Useful built-ins: Size.values() gives all constants in order, Size.valueOf("LARGE") turns text into a constant, name() gives its name and ordinal() its position, counting from 0. Enums also work in switches, and compare safely with == because each constant exists exactly once.
A record is a class whose whole job is to hold some values. One line declares the fields, and Java writes the rest:
public record OrderLine(String drink, Size size, int cups) {
public OrderLine { // compact constructor: validation
if (cups < 1) throw new IllegalArgumentException("cups must be at least 1");
}
public int totalCents() { return size.priceCents() * cups; }
}From that header, Java generates:
- private final fields, so a record cannot be changed after creation
- a constructor taking all three values in order
- accessor methods named exactly like the fields:
drink(),size(),cups(), with nogetprefix equalsandhashCodethat compare the values, and a readabletoString, such asOrderLine[drink=Latte, size=LARGE, cups=2]
The shortcut
Ask two questions about any new type. "Is the list of possible values fixed and known now?" Yes → enum. "Is it just a bundle of values that should not change?" Yes → record. Otherwise, write an ordinary class.
Size
Exactly three possibilities, known today: an enum,
Size.
Drills
Answer fast — trust the rule.
How do you read the cup count of OrderLine line?
What is Size.MEDIUM.ordinal()?
Two new OrderLine("Latte", Size.LARGE, 2) objects are compared. What are a.equals(b) and a == b?
What does line.cups = 3; do for a record?
What does System.out.println(new OrderLine("Mocha", Size.SMALL, 1)); print?
Remember
- Fixed choices become an enum; plain unchanging data becomes a record.
- Records give you fields, constructor, accessors, equals, hashCode and toString.
- Traps:
getCups()on a record, and trying to change a record's field.
