Preamble
Records (Java 16+) are nominal tuples: immutable data carriers with constructor, equals, hashCode, and toString generated from the state description. The spirit matches Python NamedTuple and frozen dataclasses (dataclasses and typing.NamedTuple for Small Models): say “this value is data,” not “this class is a mini-framework.”
Design guidance
Keep records small and focused. If invariants matter—non-negative prices, normalized emails—use compact constructors to validate. Avoid stuffing domain behavior that belongs in services; records are not an excuse for anemic-god-objects in reverse.
Concurrency and reasoning
Immutability makes shared reads across threads safer—no more “who last set this field?” mysteries. That foreshadows 2025’s BEAM message passing and Rust ownership: different mechanisms, same desire to localize mutation.
API and persistence boundaries
Records excel at DTOs crossing HTTP/gRPC boundaries and at query result shapes inside repositories. Map them explicitly at persistence edges so ORM entities do not leak upward.
Conclusion
Records reduce noise and clarify intent. typing in Practice: Protocols, Union, and TypedDict returns to Python typing for structural boundaries at module edges.