Course contents

final field semantics

The Java Memory Model's special promise for final fields: the freeze at the end of the constructor, why String and records are safe to share, how letting this escape voids it, why final is shallow, and how to share reloadable config with immutable snapshots.

PremiumOften askedLesson21 min readAdvancedReviewed Oct 2026 · Java 21
On this page
  1. Picture it first: a whiteboard vs a printed certificate
  2. Under the hood: what the freeze promises
  3. Why String is safe to share
  4. The big caveat: this must not escape
  5. final freezes the arrow, not the box
  6. Sharing a config object across threads
  7. Real world
  8. Advanced: how the freeze is implemented, and where it leaks
  9. How to say it in the interview

🔏 What are final field semantics?

The Java Memory Model gives final fields one special promise (JLS 17.5): if another thread sees a reference to an object after its constructor finished, it sees the values the constructor put in that object's final fields, with no locks and no volatile. Think of a certificate that gets printed and stamped before anyone is allowed to read it. Plain fields get no such promise: a thread that grabs the object through a race can see 0 or null where you wrote 5432.

For this lesson, we'll learn what that promise covers, the "freeze" that happens at the closing brace of a constructor, why String is safe to toss between threads, and the one mistake that cancels the whole deal: letting this escape while the constructor is still running. Interviewers love this topic because final looks like a compile-time keyword about reassignment, and then they ask "so is a final List thread-safe?" or "why is an immutable object safe even when published through a data race?". Those need a real model, not a slogan.

What you’ll learn

  • State the final-field guarantee of JLS 17.5: a thread that sees a reference after the constructor finished sees the constructor's final values, even through a data race
  • Explain the freeze at the end of the constructor and the reachability rule for objects and arrays referenced by final fields
  • Explain why **String and records are safe to share** without synchronization, and why plain fields in the same object are not
  • Spot the ways **this escapes a constructor** (listeners, start(), statics, inner classes) and fix them with a static factory
  • Separate a final reference from an immutable object, and use List.copyOf in a record's compact constructor
  • Apply the JCIP 3.4 immutability recipe and say why final does not publish a new reference
  • Share reloadable config with **immutable snapshots behind an AtomicReference**
  • Describe how HotSpot implements the freeze on x86 vs ARM, and the JDK 26 restrictions on mutating finals (JEP 500)

Premium lesson

Keep reading with the Java Pass

The rest of this lesson is part of Java One-Stop Interview Prep: in-depth explanations, diagrams, model answers and how to say them in the interview.

  • Picture it first: a whiteboard vs a printed certificate
  • Under the hood: what the freeze promises
  • Why String is safe to share
  • The big caveat: this must not escape
  • final freezes the arrow, not the box
  • Sharing a config object across threads
  • Real world
  • Advanced: how the freeze is implemented, and where it leaks
  • How to say it in the interview

From ₹299 · one-time payment · No auto-renewal

Practise this topicJava Memory Model: interview questions & scenarios
Further reading (13)