javabeginner

Java Records — Immutable Data Classes

Use Java records for concise immutable data carriers with built-in equals, hashCode, and toString.

java
import java.time.LocalDate;
import java.util.List;

// Basic record — generates constructor, getters, equals, hashCode, toString
public record Point(double x, double y) {
    // Compact constructor for validation
    public Point {
        if (Double.isNaN(x) || Double.isNaN(y)) {
            throw new IllegalArgumentException("Coordinates cannot be NaN");
        }
    }

    // Custom method
    public double distanceTo(Point other) {
        return Math.sqrt(Math.pow(x - other.x, 2) + Math.pow(y - other.y, 2));
    }
}

// Record with nested types
record Money(double amount, String currency) {
    public Money {
        if (amount < 0) throw new IllegalArgumentException("Amount must be positive");
        currency = currency.toUpperCase();
    }

    public Money add(Money other) {
        if (!this.currency.equals(other.currency)) {
            throw new IllegalArgumentException("Currency mismatch");
        }
        return new Money(this.amount + other.amount, this.currency);
    }
}

record Order(String id, LocalDate date, List<Money> items) {
    public Money total() {
        return items.stream().reduce(Money::add).orElse(new Money(0, "USD"));
    }
}

// Usage
class Demo {
    public static void main(String[] args) {
        var p1 = new Point(0, 0);
        var p2 = new Point(3, 4);
        System.out.println(p1.distanceTo(p2)); // 5.0

        var price = new Money(29.99, "usd");
        System.out.println(price); // Money[amount=29.99, currency=USD]

        var order = new Order("ORD-1", LocalDate.now(),
            List.of(new Money(10, "USD"), new Money(20, "USD")));
        System.out.println(order.total()); // Money[amount=30.0, currency=USD]
    }
}

Use Cases

  • Replacing verbose POJO classes with concise records
  • DTOs for API request and response objects
  • Immutable value objects in domain models

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.