iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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…