Records, versiegelte Klassen & Enums
Das moderne Java-Typsystem: Records, versiegelte Hierarchien, Pattern Matching und Enums.
Deutsche Übersetzung in Arbeit
Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.
Auf dieser Seite
Modern Java (16+) added concise tools that remove boilerplate and make your types safer and clearer: records, sealed classes, and enums. They help you say more with less code.
Enums: a fixed set of named values
An enum defines a type with a fixed set of possible values. Instead of using loose strings or magic numbers, you get a small, safe, self-documenting set.
A car's gearstick has a fixed set of positions: Park, Reverse, Neutral, Drive. You can't shift into "Banana". An enum is that gearstick - it constrains a value to a known, valid set, so invalid states are impossible.
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}Day today = Day.WEDNESDAY;
String plan = switch (today) {
case SATURDAY, SUNDAY -> "Relax";
default -> "Work";
};
System.out.println(plan); // WorkEnums can also carry data and methods:
enum Planet {
EARTH(9.81), MARS(3.71);
private final double gravity;
Planet(double gravity) { this.gravity = gravity; }
double weight(double mass) { return mass * gravity; }
}Prefer enums over string constants
Using "WEDNESDAY" as a raw string invites typos ("WENSDAY") that compile fine
but fail at runtime. An enum catches such mistakes at compile time and enables
exhaustive switch handling. Reach for enums whenever a value has a fixed set of
options.
Records: data classes without the boilerplate
Before records, a simple data holder required a constructor, getters,
equals(), hashCode(), and toString() - dozens of lines for something
trivial. A record generates all of that automatically.
record Point(int x, int y) { }That single line gives you:
- a constructor
Point(int x, int y) - accessor methods
x()andy() - sensible
equals(),hashCode(), andtoString() - immutability - a record's fields can't change after creation
Point p = new Point(3, 4);
System.out.println(p.x()); // 3
System.out.println(p); // Point[x=3, y=4]
Point q = new Point(3, 4);
System.out.println(p.equals(q)); // true - value equality for free!A record is like a filled-out form: name here, address there - a fixed set of fields, filled once, then read many times. It's about carrying data, not behaving. When your class is really just data, make it a record.
Sealed classes: controlling who can extend
A sealed class or interface restricts which classes may extend or implement it. You explicitly list the permitted subtypes - no surprises.
sealed interface Shape permits Circle, Rectangle { }
record Circle(double radius) implements Shape { }
record Rectangle(double width, double height) implements Shape { }Now Shape has exactly two implementations, and Java knows it. This pairs
beautifully with switch pattern matching, which can be exhaustive - the
compiler guarantees you've handled every case:
double area = switch (shape) {
case Circle c -> Math.PI * c.radius() * c.radius();
case Rectangle r -> r.width() * r.height();
// no 'default' needed - the compiler knows these are the only options
};Why 'sealing' is powerful
Sealed types let you say "this is a closed set of possibilities." Combined with records and pattern matching, they make modeling data - like the results of an operation, or the shapes in a drawing app - remarkably safe and expressive. Add a new subtype, and the compiler flags every switch you forgot to update.
Putting it together
sealed interface Payment permits Cash, Card { }
record Cash(double amount) implements Payment { }
record Card(double amount, String number) implements Payment { }
String describe(Payment p) {
return switch (p) {
case Cash c -> "Cash: $" + c.amount();
case Card c -> "Card ending " + c.number();
};
}Concise, immutable, type-safe, and exhaustive - modern Java at its best.
Quick check
What does declaring 'record Point(int x, int y) {}' give you automatically?
Key takeaways
- Enums define a fixed, type-safe set of named values and can carry data and methods.
- Prefer enums over raw string or int constants - mistakes are caught at compile time.
- Records are concise, immutable data classes that auto-generate constructor, accessors, equals, hashCode, and toString.
- Sealed classes/interfaces restrict which types may extend them via a 'permits' list.
- Sealed types plus record patterns enable exhaustive switch - the compiler ensures every case is handled.
One more essential OOP topic remains: how objects are compared for equality, and why immutability makes everything simpler. That's next.