Records
Records are immutable data carriers — one declaration generates the constructor, accessors, equals, hashCode, and toString. They cannot be extended and their fields are final. Use them for DTOs, query results, value objects, and tuple-like return types; reach for a class only when behaviour or mutation is needed.
Records, compact constructors, with-patterns
EXAMPLE
public class RecordsDemo {
// 1) Minimal record — one line
public record Point(double x, double y) {}
// 2) Compact constructor for validation (no field assignment needed)
public record Email(String value) {
public Email {
if (value == null || !value.contains("@"))
throw new IllegalArgumentException("bad email: " + value);
value = value.toLowerCase(); // normalise before assignment
}
}
// 3) Records can have static factories and instance methods
public record Money(long cents, String currency) {
public static Money aud(double dollars) {
return new Money(Math.round(dollars * 100), "AUD");
}
public Money plus(Money other) {
if (!currency.equals(other.currency))
throw new IllegalStateException("currency mismatch");
return new Money(cents + other.cents, currency);
}
}
// 4) Records implement interfaces freely
public sealed interface Shape permits Circle, Square {}
public record Circle(double radius) implements Shape {}
public record Square(double side) implements Shape {}
// 5) Pattern matching on records (Java 21+)
public static double area(Shape s) {
return switch (s) {
case Circle(double r) -> Math.PI * r * r;
case Square(double a) -> a * a;
};
}
public static void main(String[] args) {
var p = new Point(1, 2);
System.out.println(p); // Point[x=1.0, y=2.0]
System.out.println(p.x() + p.y()); // 3.0 — generated accessors
var e = new Email("ALICE@example.com");
System.out.println(e.value()); // alice@example.com (normalised)
var total = Money.aud(19.95).plus(Money.aud(30.00));
System.out.println(total); // Money[cents=4995, currency=AUD]
System.out.println(area(new Circle(5))); // 78.539...
}
}
Why it matters
Records replace the entire Lombok @Value / @Data ceremony with a language feature. Once your team is on Java 17+, prefer them as the default for "just data" — they read better in code review, serialize predictably, and pattern-match cleanly in switch.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
public record Point(int x, int y) {}
Point p = new Point(3, 4);
System.out.println(p.x() + "," + p.y());
Try it Yourself »
Discussion
Loading…