skip to content

Initialization

The precise order in which static and instance initializers, field initializers and constructors run, plus the rules for final fields. Output-prediction questions in this area are an interview staple.

part ofJavaoverview, primer and where to startread it →
on this pageshow

explore

questions

10

What are the rules for initializing a final field in Java, and what does 'definitely assigned exactly once' mean?

level: juniorimportance: must knowfreq 70%

answer

  1. Assign once, never change
  2. Three spots: declaration, instance block, every constructor
  3. Compiler proves it via definite-assignment analysis
  4. final reference vs final object contents

basics

~20 s

A final field must be given a value exactly once and can never be changed afterward. You can set it where you declare it, in an instance initializer block, or in every constructor. If you try to leave it unset or assign it twice, the code will not compile.

solid answer

~40 s

A final field is one whose value cannot change after it is assigned. The Java compiler enforces that each final instance field is 'definitely assigned exactly once' on every code path that completes an object's construction: it must be set either at its declaration, in an instance initializer block, or in each constructor before the constructor finishes. The compiler rejects code where a final field might be read before assignment, left unassigned, or assigned more than once. This guarantee is checked at compile time, not runtime. The benefit is immutability of that field: once constructed, the reference or value it holds is fixed, which makes objects easier to reason about and safe to share. final on a field is different from final on a method (cannot override) or a class (cannot subclass).

go deeper

for a junior

Knows a final field is set once and cannot change, and can name the declaration vs constructor assignment options.

for a middle

Explains 'definitely assigned exactly once', distinguishes final reference from final object contents, and knows the three assignment locations.

for a senior

Discusses compiler definite-assignment analysis across branches and ties final fields to immutability and safe construction.

for a principal

Relates final-field semantics to the Java Memory Model's safe-publication guarantees and to immutable-object design as an API/concurrency strategy.

## What 'final' means on a field In Java, the keyword **final** applied to a field (a variable that belongs to an object or class) means the field can be **assigned a value only once**. After that single assignment, any attempt to change it is a **compile-time error** — the program will not compile. A **field** is a variable declared inside a class but outside any method, e.g. `private final int x;`. An **instance field** belongs to each object; a **static field** belongs to the class itself. ## 'Definitely assigned exactly once' The Java Language Specification requires that a `final` field be **definitely assigned exactly once**. Two parts: - **Definitely assigned** — on *every* possible execution path that finishes constructing the object, the field has been given a value. The compiler performs *definite-assignment analysis*: it traces all branches (if/else, switch, loops, try/catch) and proves the field is set on each one. If even one path could leave it unset, compilation fails. - **Exactly once** — the field is assigned **no more than one time**. Assigning it a second time (even on a different branch where it was already set) is a compile error. ## Where you may assign it There are exactly three legal places to assign a `final` instance field: 1. **At the declaration (field initializer):** ```java private final int size = 10; ``` 2. **In an instance initializer block** (a `{ ... }` block in the class body that runs before constructor bodies): ```java private final int size; { size = 10; } ``` 3. **In a constructor** — but then it must be assigned in *every* constructor on every path (this is the 'blank final' case, covered separately). A `final` field is assigned in **one** of these mechanisms, not several. For example, if you give it a value at the declaration, you cannot also assign it in a constructor. ## Why the rule exists The point is **immutability**: once an object is fully constructed, a `final` field never changes. This makes the value safe to read repeatedly, easier to reason about, and (under the Java Memory Model) safely visible to other threads after construction. The compiler's exactly-once guarantee means you can trust that a `final` field is never accidentally reassigned or left as a default value. ## What it does NOT mean - `final` makes the **reference/variable** unchangeable, not the **object it points to**. `final List<String> list = new ArrayList<>();` still lets you call `list.add(...)` — the list contents are mutable; you just can't repoint `list`. - `final` on a field is unrelated to `final` on a method (can't be overridden) or `final` on a class (can't be extended). ## A worked example ```java class Circle { private final double radius; // blank final private final double pi = 3.14159; // assigned at declaration Circle(double r) { radius = r; // assigned exactly once in the constructor } } ``` Here `pi` is set at its declaration; `radius` is a blank final set once in the constructor. Both are 'definitely assigned exactly once'.

  • Does final on a field make the object it points to immutable?
    No. final fixes the variable binding — you cannot reassign the field — but the object it references can still be mutated (e.g. adding to a final List). True immutability requires the referenced type to also be immutable.
  • Can a final field be left unassigned?
    No. The compiler requires it to be definitely assigned on every construction path. A blank final that some constructor or path fails to assign is a compile error.

saying these in an interview costs you the question

  • Thinking final makes the referenced object immutable (it only fixes the variable)
  • Believing the check happens at runtime — it is compile-time
  • Claiming you can assign a final field in any method, not just constructors/initializers

context

open as a page

In Java, what is the difference between static initialization and instance initialization, and when does each one run?

level: juniorimportance: must knowfreq 70%

basics

~20 s

Static initializers (static fields and static blocks) run once, when the class is first loaded. Instance initializers (instance fields and instance blocks) run every time you create an object with new, just before the constructor body.

open as a page

What is a 'blank final' field and what must every constructor do for it?

level: middleimportance: must knowfreq 62%

basics

~20 s

A blank final is a final field declared without a value, like private final int id;. Because it has no initializer, every constructor must assign it exactly once before the constructor ends. If any constructor leaves it unset, the code won't compile.

open as a page

Walk through the exact order of operations when you call new on a subclass: default values, super constructor, instance initializers, field initializers, and the constructor body. Why is this order important?

level: middleimportance: must knowfreq 68%

basics

~20 s

On new: fields first get default values (0/null/false), then the parent constructor runs fully, then this class's instance field initializers and instance blocks run top-to-bottom, and finally the constructor body runs. Parent is always fully built before the child.

open as a page

How do field initializers and instance initializer blocks interact when assigning final fields, and in what order do they run relative to the constructor?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Field initializers and instance initializer blocks run in the order they appear in the source, after the superclass constructor and before the rest of the constructor body. A final field can be set in one of these places or in the constructor, but only once total.

open as a page

How does initialization of a static final field (a constant) differ from an instance final field, and what is a compile-time constant?

level: seniorimportance: should knowfreq 45%

basics

~20 s

A static final field belongs to the class, not an object, so it is set once at class load time — either at its declaration or in a static initializer block, never in a constructor. If its value is a constant expression known at compile time, the compiler may inline it directly into other code.

open as a page

What initialization-order pitfalls can produce wrong values, NullPointerExceptions, or ExceptionInInitializerError, and how do you avoid them?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Common traps: a static field reads another static field declared later (gets default value), a constructor calls an overridable method that sees uninitialized subclass fields, and an exception in a static initializer becomes an ExceptionInInitializerError that permanently breaks the class. Avoid by ordering declarations carefully and not calling overridable methods from constructors.

open as a page

How does static initialization run across a class hierarchy, and exactly when is a superclass's static initialization triggered relative to a subclass's?

level: seniorimportance: should knowfreq 45%

basics

~20 s

A class's static initialization runs once, and a superclass is always initialized before its subclass. So when a subclass is first used, the JVM initializes the parent's statics first, then the child's. Each happens at most once.

open as a page

How do final instance fields interact with the Java Memory Model to provide safe publication, and what design rule does this imply for immutable objects?

level: principalimportance: should knowfreq 30%

basics

~20 s

The Java Memory Model gives a special guarantee: if you set a final field during construction and don't let the object escape before the constructor finishes, any other thread that later sees the object is guaranteed to see the correctly initialized final field, even without locks or volatile.

open as a page

How does constructor chaining with this(...) interact with instance field initializers and instance blocks, and how many times do those initializers run?

level: middleimportance: nice to knowfreq 28%

basics

~20 s

When a constructor calls this(...) to delegate to another constructor of the same class, the instance field initializers and instance blocks run only once, in the constructor that actually calls super(...). Delegating constructors do not re-run them.

open as a page