library
intermediateRecords (Java 14+)
Use records for immutable data carriers with auto-generated equals, hashCode, toString, and accessors.
A record declares the data and the compiler writes the rest.
Record = a pre-printed form with labeled fields. You fill in the values once (constructor) and they're locked. The form knows how to compare itself with other forms and describe itself.
Key Concepts
1
record Point(int x, int y) { }2
// you get, for free:
// a constructor taking (x, y)
// accessors x() and y()
// equals comparing both components
// hashCode from both
// toString -> Point[x=1, y=2]3
That replaces about fifty lines of fields, constructor, getters, equals, hashCode and toString —
and removes the chance of equals and hashCode drifting apart as fields are added.
equalshashCodetoString
4
Accessors have no get prefix.
p.x() // not p.getX()get
5
Validate with a compact constructor, which has no parameter list and no assignments:
6
record Range(int lo, int hi) {
Range {
if (lo > hi) throw new IllegalArgumentException("lo > hi");
}
}7
You may also normalise there — assigning to the parameter changes what gets stored:
8
record Name(String value) {
Name { value = value.trim(); }
}9
You can add anything that is not state.
record Point(int x, int y) {
double distance() { return Math.sqrt(x * x + y * y); }
static Point origin() { return new Point(0, 0); }
}10
What a record cannot do.
extend a class it already extends java.lang.Record
be extended it is implicitly final
hold mutable fields every component is final
add an instance field outside the component list11
"Immutable" has a limit worth knowing.
record Order(List<Item> items) { }12
The items reference is final; the list is not. A caller can still add to it. For real immutability, copy in
the constructor: items = List.copyOf(items).
itemsitems = List.copyOf(items)
13
Where records fit. DTOs, value objects, compound map keys, and returning two values from a method
without inventing a class.
14
And they pair with sealed interfaces for exhaustive pattern matching, since a record is already final.
15
What the interviewer is probing.1. "Is a record immutable?" Probing: the limit of the guarantee. Stalls: "Yes, completely."
Moves up: its components are final, but a component holding a List is still mutable by whoever
passed it — copy in a compact constructor for real immutability.
16
2. "How do you validate a record component?" Probing: the compact constructor. Stalls: "You
cannot." Moves up: a compact constructor with no parameter list and no assignments, which can
throw or normalise by assigning to the parameter.
17
3. "What can a record not do?" Probing: the constraints. Stalls: "Nothing special." *Moves
up:* extend a class, be extended, hold mutable instance fields, or declare instance fields outside
the component list.
18
4. "Where do records fit beyond DTOs?" Probing: breadth. Stalls: "Just data transfer."
Moves up: value objects, compound map keys, multiple return values, and sealed hierarchies for
exhaustive pattern matching, since records are implicitly final.