Sitemap

Understanding Static and Instance Initializer Blocks in Java

4 min readMar 7, 2025

--

Press enter or click to view image in full size

Java provides two types of initializer blocks — static blocks and instance initializer (non-static) blocks. These blocks are used to initialize variables, perform setup tasks, and execute code at specific times during the program’s execution. Let’s break them down in a simple and easy-to-understand manner.

Static Block

What is a Static Block?

A static block is used to initialize static variables or execute code that needs to run once when the class is loaded. It is defined using the static keyword and enclosed within curly braces {}. Static blocks execute even before the mainmethod is called.

Key Characteristics:

  • Runs when the class is loaded into memory (which occurs before any object of that class is created).

Example:

class MyClass {
static int x;
// Static block
static {
x = 10;
System.out.println("Static block executed. x = " + x);
}
// Constructor
MyClass() {
System.out.println("Constructor executed");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Main method started");
MyClass obj = new MyClass();
}
}

Output:

Main method started
Static block executed. x = 10
Constructor executed

Execution Flow:

  • Main method starts.
  • MyClass is referenced (new MyClass()), causing MyClass to load and its static block to execute.
  • MyClass's instance initializer block runs.
  • MyClass's constructor runs.

Instance Initializer Block (Non-Static Block)

What is an Instance Initializer Block?

An instance initializer block is executed every time an object is created, before the constructor. It is useful when you need to initialize instance variables across multiple constructors or perform complex setup tasks.

Key Characteristics:

  • Runs every time an object of the class is instantiated.
  • Executes before the constructor.
  • Useful for reusing initialization logic in multiple constructors.

Example:

class MyClass {
int x;

// Instance initializer block
{
x = 10;
System.out.println("Instance initializer block executed");
}
// Constructor
MyClass() {
System.out.println("Constructor executed");
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
}
}

Output:

Instance initializer block executed
Constructor executed

Why Use Instance Initializer Blocks?

1. Reusing Initialization Logic Across Multiple Constructors

class MyClass {
int x;
// Instance initializer block
{
x = 10;
System.out.println("Instance initializer block executed");
}
MyClass() {
System.out.println("Default constructor executed");
}
MyClass(int y) {
System.out.println("Parameterized constructor executed");
}
}

Output:

Instance initializer block executed
Default constructor executed
Instance initializer block executed
Parameterized constructor executed

2. Performing Complex Initialization

class MyClass {
int x;

// Instance initializer block
{
if (System.getProperty("os.name").contains("Windows")) {
x = 100;
} else {
x = 200;
}
System.out.println("Instance initializer block executed. x = " + x);
}

// Constructor
MyClass() {
System.out.println("Constructor executed");
}
}

public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass();
}
}

Output (on Windows):

Instance initializer block executed. x = 100
Constructor executed

3. Initializing Anonymous Classes

Get Prithukathet’s stories in your inbox

Join Medium for free to get updates from this writer.

Instance initializer blocks are particularly useful in anonymous classes, where you cannot define a constructor.

interface MyInterface {
void display();
}

public class Main {
public static void main(String[] args) {
MyInterface obj = new MyInterface() {
int x;

// Instance initializer block
{
x = 10; // Initialize x
System.out.println("Instance initializer block executed");
}

@Override
public void display() {
System.out.println("x = " + x);
}
};

obj.display();
}
}

Output:

Instance initializer block executed
x = 10

4. Order of Execution

The instance initializer block is executed after the call to super() in the constructor but before the rest of the constructor's body. This ensures that the instance variables are initialized before any additional logic in the constructor.

Example:

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

class Child extends Parent {
int x;

// Instance initializer block
{
x = 10;
System.out.println("Instance initializer block executed");
}

// Constructor
Child() {
System.out.println("Child constructor executed");
}
}

public class Main {
public static void main(String[] args) {
Child obj = new Child();
}
}

Output:

Parent constructor executed
Instance initializer block executed
Child constructor executed

Explanation:

  1. The super() call in the Child constructor executes the Parent constructor.
  2. The instance initializer block is executed next.
  3. Finally, the rest of the Child constructor is executed.

Combining Static and Non-Static Blocks

Example:

class MyClass {
static int staticVar;
int instanceVar;

// Static block 1
static {
staticVar = 10;
System.out.println("Static block 1 executed. staticVar = " + staticVar);
}
// Static block 2
static {
staticVar = 20;
System.out.println("Static block 2 executed. staticVar = " + staticVar);
}
// Non-static block 1
{
instanceVar = 100;
System.out.println("Non-static block 1 executed. instanceVar = " + instanceVar);
}
// Non-static block 2
{
instanceVar = 200;
System.out.println("Non-static block 2 executed. instanceVar = " + instanceVar);
}
// Constructor
MyClass() {
System.out.println("Constructor executed");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Main method started");
MyClass obj = new MyClass();
}
}

Output:

Main method started
Static block 1 executed. staticVar = 10
Static block 2 executed. staticVar = 20
Non-static block 1 executed. instanceVar = 100
Non-static block 2 executed. instanceVar = 200
Constructor executed

Execution Order:

  • Main Method starts (Prints "Main method started").
  • Static Blocks execute (When MyClass is loaded upon reaching new MyClass()).
  • Non-Static Blocks execute (Before the constructor call).
  • Constructor executes last.

When to Use Static and Non-Static Blocks?

Static Blocks:

  • When you need to initialize static variables.
  • When performing one-time setup tasks (e.g., loading configuration files).

Non-Static Blocks:

  • When you want to initialize instance variables before the constructor.
  • When you have multiple constructors and need common initialization logic.
  • When defining anonymous classes where constructors are not allowed.

Key Takeaways:

Static Blocks:

  • Executed once when the class is loaded.
  • Used for static variable initialization.

Non-Static Blocks:

  • Executed every time an object is created.
  • Used for instance variable initialization.

Execution Order:

  • Static blocks → Main method → Non-static blocks → Constructor.

Understanding these blocks helps in writing cleaner and more efficient Java programs, ensuring better code organization and initialization logic.

--

--