MediumExperience level: 3-5 years · 8-15 years1 min read

How do you design a correct immutable class for a multi-threaded service?

Reviewed by Gurusankar M.

Asked inAmazonMicrosoftDeloitte
#immutability#thread-safety#defensive copy#records#value object
Report issue

Short Answer

Make the class final, all fields private final, no setters, initialize in the constructor, and defensively copy any mutable inputs/outputs (collections, dates). Java records do most of this — but you must still deep-copy mutable members.

On this page

Concept Made Simple

Coffee Chat Question

“How do you design a correct immutable class for a multi-threaded service?”

Remember It Faster

Mind Map Answer

final class
no subclass can add mutability
private final fields
set once
no setters
no post-construction change
defensive copy
in (ctor) and out (getters)

Learn by Doing

Hands-on Keyboard

java
public final class Money {
    private final long cents;
    private final List<String> tags;
    public Money(long cents, List<String> tags) {
        this.cents = cents;
        this.tags = List.copyOf(tags); // defensive copy in
    }
    public List<String> tags() { return tags; } // already unmodifiable
}

Think Beyond the Expected

What If?

A record holds a List field — is it truly immutable?

No. The record reference is final, but the List itself is still mutable, so callers can change its contents. You must copy it in the compact constructor (List.copyOf) and expose an unmodifiable view.

Real World

Immutable value objects (Money, DateRange, Coordinates) are shared freely across threads with zero synchronization — the backbone of thread-safe domain models and functional-style services.

Interviewer's Expectation

Keywords they're listening for:

  • final class/fields
  • no setters
  • defensive copies of mutable members
  • records caveat
  • thread-safety benefit

Common Mistakes

  • Storing a mutable collection/date without copying
  • Returning the internal mutable reference from a getter
  • Forgetting final on the class, allowing a mutable subclass

Best Practices

  • Defensive-copy mutable inputs and outputs
  • Prefer records + List.copyOf for value objects
  • Provide with-style copy methods for 'changes'

Follow-up Questions

  1. How do records help, and where do they fall short?
  2. How do you 'modify' an immutable object (with-er / copy)?
  3. Why are immutable objects inherently thread-safe?

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: "How do you design a correct immutable class for a multi-threaded service?"

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?

Affiliate links

Equipment for a comfortable, productive setup.

As an Amazon Associate I earn from qualifying purchases.