skip to content

When a class has multiple static initializer blocks and static field initializers interleaved, in what order do they execute?

level: middleimportance: must knowfreq 60%

answer

  1. One merged sequence, strict textual (top-down) order
  2. Field initializers + blocks interleaved, not separate phases
  3. Read only what's declared above; below = default value
  4. Forward WRITE legal, forward READ illegal
  5. Superclass initializes before subclass

basics

~20 s

They run top to bottom, in the exact order they appear in the source code. Static field initializers and static blocks are treated as one combined sequence, and each runs once when the class is initialized.

solid answer

~50 s

Static field initializers and static initializer blocks are not two separate phases — the JVM merges them into a single list in **textual (source) order** and runs that list top to bottom, once, at class initialization. So a static field declared above a block can be read inside that block, but a field declared *below* a block has not been initialized yet when the block runs (it holds its default value). A subtle but important exception: you *can* assign to a static field that is declared below a block (a 'forward write' is legal), but you generally cannot *read* it before its declaration. Superclass initialization runs before the subclass's. The practical rule: order your static declarations and blocks so that anything you read has already been initialized above it; relying on a value set later is a classic bug.

go deeper

for a junior

Knows static blocks run top to bottom and that there can be more than one.

for a middle

Understands field initializers and blocks form one interleaved sequence in textual order, and that reading a field declared below yields its default.

for a senior

Can explain the forward-reference rule (write allowed, read disallowed) and superclass-before-subclass initialization ordering.

for a principal

Predicts subtle outcomes across inheritance + interleaving, and recognizes order-dependence as a maintainability hazard worth refactoring away from in large classes.

## The core rule: textual order, one merged sequence A class body can contain both **static field initializers** (`static int a = 1;`) and **static initializer blocks** (`static { ... }`). It's tempting to think Java runs all field initializers first and then all blocks — it does **not**. Instead, the compiler/JVM collects every static initializer (field-assignment *and* block) into **one sequence, in the exact order they appear in the source file**, and executes that sequence top to bottom during class initialization. Each runs exactly once. ```java class Demo { static int a = 1; // (1) static { System.out.println(a); } // (2) prints 1 — a already set above static int b = a + 10; // (3) b = 11 static { System.out.println(b); } // (4) prints 11 } // Output when Demo is initialized: 1 then 11 ``` ## Why ordering matters: reading a not-yet-initialized field Because execution is strictly top-down, a static block can only safely **read** static fields **declared above it**. A field declared *below* still holds its **default value** (0 for numbers, `false` for boolean, `null` for references) when an earlier block runs: ```java class Trap { static { System.out.println(x); } // prints 0 — x not yet initialized static int x = 42; } ``` This is a frequent interview trap and a real-world bug source. The fix is to declare/initialize the field *before* the block that needs it. ## The forward-reference subtlety: write is allowed, read is not Java's 'illegal forward reference' rule restricts *reading* a static field before its textual declaration, but **assignment** to it is permitted. So this compiles: ```java class FwdWrite { static { y = 5; } // legal: writing y before its declaration static int y; // y ends up 5 if no later initializer overwrites it } ``` Note that if the field also has an inline initializer below, that initializer runs *after* the block (textual order) and would overwrite the block's write. ## Inheritance: superclass before subclass When a subclass is initialized, the JVM guarantees the **superclass is fully initialized first**. So the order across a hierarchy is: superclass static initializers (in their textual order) → then subclass static initializers (in their textual order). Instance-level initialization (instance initializers + constructors) is a separate, later concern and runs per object. ## What does NOT change the order - Mixing field initializers and blocks freely — still strict textual order. - The number of blocks — three blocks run in their three positions. - Access modifiers or field types — irrelevant to ordering. ## Mental model to carry into an interview Think of the JVM as flattening the class's static parts into one script, line by line, and executing it once. 'Can this block see that field?' → 'Is the field's initialization line *above* this block?' If yes, it's the real value; if no, it's the default (for reads) — and writing ahead is the only forward operation allowed.

  • What value does a static block print if it reads a static field declared after it?
    The field's default value (0, false, or null), because initialization is strictly top-down and the field's initializer hasn't run yet.
  • If a block assigns to a field declared below it, and that field also has an inline initializer, what's the final value?
    The inline initializer wins, because it appears later in textual order and runs after the block, overwriting the block's write.

saying these in an interview costs you the question

  • Saying all field initializers run first, then all blocks — they're interleaved in source order
  • Claiming a block can read a field declared below it and get its assigned value (it gets the default)
  • Forgetting that superclass static init precedes subclass static init
  • Confusing static initialization order with instance initialization order

context