static ·
‹ Previous Next ›
⏱ 5 min read Modified: 2026-09-26

Static Block in Java: the Static Initialization Block Explained

Run the program below and it prints Static block initialized. and waits for input before main() has executed a single line. That code sits inside a static block, and the JVM runs it before main() is ever called.

A static block in Java (also called a static initialization block, static initializer, or static initializer block) is a block of code in curly braces, declared with the static keyword directly in the class body, outside any method or constructor. It runs once, when the class is initialized, and is used to set up static fields that a simple assignment cannot handle. Java also has a second kind of block, the instance initializer ({ ... }, without static), which runs on every object creation, before the constructor body.

Static initialization block syntax

When a static field needs computation rather than a plain assignment, Java gives you a static block: the static keyword followed by curly braces. A static block runs once per class initialization — when the JVM initializes the class, before main() is called and before the first object is created. For example:

import java.util.Scanner;

public class StaticBlockExample {
    static String a;

    static {
        System.out.println("Static block initialized.");
        Scanner scanner = new Scanner(System.in);
        a = scanner.nextLine();
    }

    public static void main(String[] args) {
        System.out.println("a = " + a);
    }
}

If you type Hello after running it, the output is:

Static block initialized.
Hello
a = Hello

The static block ran first and assigned a, and only then did the JVM call main(). For more on static fields themselves, see Static Variables in Java.

Good to know

Reading from the console in a static block is a handy way to show exactly when it runs, but real code should not do this: a static block should prepare class data quickly and predictably. Keep user input, network calls, and other "slow" logic in ordinary methods.

Why use a static block

A simple static variable is fine as an inline assignment: static int max = 100;. A static block earns its place when one expression is not enough:

  • filling a static collection or array in a loop;
  • initialization that can throw an exception you need to handle in a try-catch;
  • one-time class setup — for example loading a native library with System.loadLibrary(...) or reading configuration;
  • several static fields that depend on each other and must be computed together.

Example: an HTTP status code lookup table, filled once when the class is initialized:

import java.util.HashMap;
import java.util.Map;

public class HttpStatus {
    static final Map<Integer, String> STATUSES = new HashMap<>();

    static {
        STATUSES.put(200, "OK");
        STATUSES.put(404, "Not Found");
        STATUSES.put(500, "Internal Server Error");
    }

    public static void main(String[] args) {
        System.out.println(STATUSES.get(404)); // Not Found
    }
}

For small immutable collections, modern Java (9+) often replaces a static block with a factory method: static final Map<Integer, String> STATUSES = Map.of(200, "OK", 404, "Not Found");. But when the data must be computed, read, or wrapped in exception handling, a static block is still the right tool.

Multiple static blocks: execution order

A class can have any number of static blocks. They run top to bottom, in declaration order, interleaved with static field initializers:

public class StaticOrder {
    static int a = print("field a", 1);

    static {
        print("static block 1", 0);
    }

    static int b = print("field b", 2);

    static {
        print("static block 2", 0);
    }

    static int print(String name, int value) {
        System.out.println(name);
        return value;
    }

    public static void main(String[] args) {
        System.out.println("main: a = " + a + ", b = " + b);
    }
}

Output:

field a
static block 1
field b
static block 2
main: a = 1, b = 2

For readability, one static block placed after the static field declarations is usually enough.

Instance initializer block

The instance initializer block is declared with plain curly braces, no static. It runs on every object creation — after the parent constructor call (super(...)) and before the rest of the constructor body. Inside it you can use both static and instance fields, plus this.

public class Counter {
    static int created;
    int id;

    {
        created++;
        id = created;
        System.out.println("Instance block: id = " + id);
    }

    Counter() {
        System.out.println("Constructor Counter()");
    }

    Counter(String name) {
        System.out.println("Constructor Counter(" + name + ")");
    }

    public static void main(String[] args) {
        new Counter();
        new Counter("second");
    }
}

Output:

Instance block: id = 1
Constructor Counter()
Instance block: id = 2
Constructor Counter(second)

The compiler effectively copies the instance block's code into the start of every constructor that does not begin with this(...) (right after super(...)), so the block runs exactly once per object. That makes it useful when several constructors share common setup, though in practice the same result is usually achieved by chaining one constructor to another with this(...). Instance initializer blocks show up mostly in anonymous classes, where you cannot declare a constructor.

Static block vs instance initializer

Characteristic Static block Instance initializer
Syntax static { ... } { ... }
When it runs Once, when the class is initialized On every object creation (new)
Relative to the constructor Long before it, before the first object exists After super(...), before the constructor body
Field access Static fields only Both static and instance fields
this and super Not available Available
Checked exceptions Cannot be thrown, must be caught inside Allowed if declared by every constructor
Typical use Filling static collections, one-time class setup Shared code for several constructors, anonymous classes

Class and object initialization order

"In what order do the blocks and constructors run?" is one of the most common Java Core interview questions. Consider it with inheritance:

class Parent {
    static {
        System.out.println("1. Parent static block");
    }

    {
        System.out.println("3. Parent instance block");
    }

    Parent() {
        System.out.println("4. Parent constructor");
    }
}

class Child extends Parent {
    static {
        System.out.println("2. Child static block");
    }

    {
        System.out.println("5. Child instance block");
    }

    Child() {
        System.out.println("6. Child constructor");
    }
}

public class InitOrderExample {
    public static void main(String[] args) {
        new Child();
        System.out.println("--- second object ---");
        new Child();
    }
}

Output:

1. Parent static block
2. Child static block
3. Parent instance block
4. Parent constructor
5. Child instance block
6. Child constructor
--- second object ---
3. Parent instance block
4. Parent constructor
5. Child instance block
6. Child constructor

The general rule:

  1. Class initialization (once): static fields and static blocks — parent first, then subclass, each in declaration order.
  2. Object creation (on every new): for each class in the hierarchy, starting with the parent — instance fields and instance blocks in declaration order, then the constructor body.

When the second object is created, the static blocks do not run again: the class is already initialized.

When does a static block run

A static block runs during class initialization, which happens lazily — on the first active use of the class:

  • creating an object with new;
  • calling a static method (including main() when the program starts);
  • accessing a static field (other than a compile-time static final constant);
  • initializing a subclass — the parent is initialized first;
  • loading the class explicitly with Class.forName("ClassName").

Declaring a variable of the class's type (StaticBlockExample x;), creating an array (new StaticBlockExample[10]), or the literal StaticBlockExample.class does not trigger a static block. A class is initialized once per classloader, so in a typical application a static block runs exactly once for the whole run of the program.

Under the hood

The JVM guarantees that class initialization completes exactly once even when several threads trigger it at the same time: the other threads wait for it to finish. This is the basis of the thread-safe lazy singleton pattern known as initialization-on-demand holder.

Things to watch out for

  • Checked exceptions. A static block cannot throw a checked exception — it must be caught inside with try-catch, or the code will not compile.
  • ExceptionInInitializerError. If a static block (or a static field initializer) throws an unchecked exception, for example static int value = Integer.parseInt("abc");, the JVM wraps it in ExceptionInInitializerError. The class stays uninitialized, and every later reference to it fails with NoClassDefFoundError.
  • Illegal forward reference. A static block can assign to a field declared later, but it cannot read it by its simple name: static { System.out.println(x); } static int x = 1; is a compile error.
  • No this, no instance members. A static block runs without an object, so it cannot use this, super, or access instance fields and methods directly — the same restriction as static methods.
  • Heavy logic. Long-running operations in a static block slow down the first use of the class, and an error inside leaves the class unusable for as long as its classloader lives (in a typical application, until restart). Such code is also hard to test.
  • Double brace initialization. The idiom new HashMap<>() {{ put("a", 1); }} is an anonymous subclass with an instance initializer block. It creates an extra class and holds a reference to the enclosing object, so it is considered an antipattern; prefer Map.of(...).

Frequently Asked Questions

Can a program run without a main method using a static block?

Not anymore. Before Java 7, the JVM initialized the class first, so code in a static block ran and only then the "no main method found" error appeared. Starting with Java 7, the launcher checks for a main method before initializing the class, so a static block without main will not run.

Does accessing a static final constant trigger the static block?

If it is a compile-time constant (a primitive or a String initialized with a constant expression, such as static final int MAX = 10;) — no: the compiler inlines the value at the usage site, and the class is not initialized. If the value is computed at run time (static final Integer MAX = 10; or static final long START = System.currentTimeMillis();), accessing the field triggers class initialization and runs the static block.

How is a static block different from a constructor?

A constructor can take parameters, and only the one matching the new call runs. An instance initializer block takes no parameters and runs before the body of whichever constructor is called. A static block is not tied to objects at all: it runs once, when the class is initialized.

Can a static block run more than once?

Not within one classloader: a class is initialized only once. But if the same class is loaded by different classloaders (for example, by two web applications deployed on the same application server), the JVM treats them as different classes, and the static block runs once for each of them.

Is a Java static initialization block thread-safe?

The initialization itself is: the JVM locks the class while the static block runs, and other threads wait for it to finish, so within one classloader the block never runs concurrently or twice. But if the static block fills a mutable collection (for example a HashMap) that other threads later modify, those later changes still need their own synchronization.

Comments

Please log in or register to have a possibility to add comment.