Medium👤 3-5 years👤 8-15 years 3 min read

Records vs Lombok @Value for DTOs — Interview Questions

Asked inAmazonMicrosoftDeloitte
#records#lombok#dto#immutability#java 17
Report issue

⚡ Short Answer

Both produce an immutable class with a canonical constructor, accessors, equals(), hashCode(), and toString() — but Records (finalized in Java 16) are a real language feature the compiler generates and understands directly, with no build-time dependency, no annotation-processor step, and first-class support in pattern matching and switch; Lombok's @Value is a compile-time annotation processor bolted onto a normal class, which predates Records and still offers things Records don't, like builder-style generation (@Builder) and the ability to extend a superclass, since a Record can't extend another class.

Coffee Chat Question

Concept Made Simple

Records vs Lombok @Value for DTOs — what do you actually gain and lose?

🧠Mind Map Answer

Remember It Faster

The core distinction is language feature vs external tool: a Record's shape is enforced by javac itself, so every Java developer and every other tool (IDEs, pattern matching, reflection) understands it uniformly. Lombok generates equivalent bytecode via annotation processing, which works well but is invisible in the source until you know Lombok's conventions.

RecordsLanguage feature (Java 16+); no dependency; can't extend a class
Lombok @ValueAnnotation processor; needs the Lombok dependency + IDE plugin
Pattern matchingRecords get first-class deconstruction patterns; Lombok classes don't
Builders / inheritanceLombok (@Builder, extends) still fills gaps Records don't cover

Key takeaway: on Java 17+, Records are the default choice for a plain immutable data carrier; Lombok remains relevant specifically where its extra generators (builders, inheritance-friendly value classes) cover a gap Records structurally can't.

⌨️Hands-on Keyboard

Learn by Doing

java
// Record: compiler-generated, no dependency, with a validating compact constructor
public record OrderDto(String id, BigDecimal total) {
    public OrderDto {                      // compact constructor — runs before field assignment
        if (total.signum() < 0) throw new IllegalArgumentException("negative total");
    }
}

// Lombok equivalent: same shape, requires the Lombok dependency + annotation processing
@Value
public class OrderDtoLombok {
    String id;
    BigDecimal total;
}
// Lombok can additionally generate a builder (@Builder) — Records have no built-in builder

🔥What If?

Think Beyond the Expected

Why can't a Record extend another class the way a Lombok @Value class can?

Every Record implicitly extends java.lang.Record, and Java doesn't support multiple inheritance of state — allowing a Record to also extend a user class would mean combining two sets of inherited fields in a way the language's single-inheritance model doesn't support. This is a deliberate language-level constraint, not a missing feature Lombok simply implements better.

😂Real World

Teams standardizing on Java 17+ for new services increasingly default to Records for DTOs and drop the Lombok dependency for that use case entirely, keeping Lombok (if at all) only for classes needing @Builder or inheritance Records structurally can't provide — this also removes a build-time annotation-processor dependency and IDE-plugin requirement that occasionally causes friction (stale generated code, IDE support lag on new Lombok versions).

🗣️Real Talk from Guru

If I'm starting a new Java 17+ codebase, I reach for Records first for DTOs, and only bring in Lombok for the specific gap it fills — usually @Builder on a more complex object. I wouldn't rip Lombok out of an existing large codebase just for consistency; that's churn without a real payoff.

🎯Interviewer's Expectation

Keywords they're listening for:

Knows Records are a compiler/language feature, Lombok is an annotation processorNames the compact constructor as Records' validation mechanismKnows Records can't extend a classIdentifies a concrete gap (builders, inheritance) where Lombok still applies

⚠️Common Mistakes

  • Assuming Records and Lombok @Value are strictly interchangeable
  • Not knowing Records can't extend another class
  • Migrating everything to Records without checking for a builder/inheritance dependency

Best Practices

  • Default to Records for new immutable DTOs on Java 17+
  • Keep Lombok only for the specific gaps Records don't cover
  • Use a compact constructor for Record-level validation instead of a separate factory

🔁Follow-up Questions

  • 1How does a Record's compact constructor differ from a canonical constructor?
  • 2How do Records interact with pattern matching in a switch expression?
  • 3Would you migrate an existing large Lombok codebase to Records — why or why not?

🧩Related Technologies

LombokPattern MatchingImmutability

Continue Learning with AI

Take this question deeper with your favourite AI assistant. Pick a depth, copy the prompt, or open it directly — AI is your learning companion, not a shortcut.

Plain-language foundations

I'm preparing for a software engineering interview and want to understand this from scratch, as a beginner.

Topic: OOP (Core Java)
Interview question: "Records vs Lombok @Value for DTOs — what do you actually gain and lose?"

Please:
1. Explain the core idea in simple, plain language, using an everyday analogy.
2. Define any technical terms you use.
3. Walk through one small, concrete example.
4. Finish with a single sentence I can easily remember.

Keep the tone friendly and assume I'm new to this topic.
Open inChatGPTGeminiClaude

Was this answer helpful?

Support our platform by exploring our recommended products.

As an Amazon affiliate, purchases through these links may earn us a small commission — at no extra cost to you. It helps keep Full Stack Interview Guru free.

Related Questions