Java Records — What the Compiler Generates
Fast recall
Quick revision
Core answer
Whether you know the accessor naming convention, the equals/hashCode contract, and the limitations (no mutable state, no extending a class).
Expecting getX() style accessors — records use x() directly. Also thinking records can extend another class (they extend Record implicitly).
Discuss compact constructors for validation, custom accessor overriding, and how records interact with Jackson deserialization.
Interview-ready guide
Interview answer
record Point(int x, int y) {} tells the compiler to generate six things: a final class extending java.lang.Record, private final fields, a canonical constructor, accessor methods x() and y() (not getX()), and equals(), hashCode(), toString() covering all components.
Generated equals/hashCode mechanism:
- Uses
invokedynamicandObjectMethods.bootstrap— a JVM-level mechanism that generates component-specific comparison at runtime - Not static code like Lombok or IDE generation — type-safe and correct by default
Customization:
- Compact constructors for validation:
Range { if (min > max) throw ...; }— no parameter list, field assignment happens automatically after the body - Can override any generated method, but overriding
equals()to exclude a component breaks transparency guarantees that tools rely on
Mutable component gotcha:
- A record holding
Listreturns the original reference from its accessor — callers can mutate the internal state - Fix: defensively copy in the compact constructor —
items = List.copyOf(items)
I recommend records as the default for DTOs and composite return types — they provide correct value semantics that manual implementations frequently get wrong.
Java Records — What the Compiler Generates
Direct Answer
A Java record is a transparent, immutable data carrier. For record Point(int x, int y), the compiler generates: a canonical constructor, private final fields, public accessor methods x() and y() (not getX()), equals() based on all components, hashCode() based on all components, toString() returning Point[x=1, y=2], and implements Serializable if you declare it. Records are implicitly final.
Deep Dive & Architecture
Varargs (`Type...
args`) = syntactic sugar — compiler converts to array.
Must be last parameter, at most one per method. Can pass 0+ args or an explicit array. Heap pollution with generics (T... args) — @SafeVarargs when provably safe. Null trap: method(null) passes as null array — args.length throws NPE. Avoid combining varargs with overloading — compiler resolution can produce surprises.
Saying Java is pass-by-reference for objects because you can modify the object's fields inside a method
Common Mistakes & Pitfalls
Expecting getX() style accessors — records use x() directly. Also thinking records can extend another class (they extend Record implicitly).
Check your understanding
Answer these without looking back at the article.
- Is Java pass-by-value or pass-by-reference?
- Varargs in Java — Variable Arguments and Heap Pollution
- What is autoboxing and unboxing in Java? What is the Integer cache trap?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.