Java Initializer Blocks
In Java, apart from constructors, we also have initializer blocks to initialize objects and classes. These blocks allow you to run specific code automatically whenever a class is loaded or an object is created.
Initializer blocks are useful when:
- You need common code across multiple constructors
- You want to run setup code before constructors
- You need to initialize static resources (like database connections, loggers, or constants)
In this guide, we’ll explore:
- What initializer blocks are
- Types of initializer blocks
- Execution order
- Examples with code
- Best practices
What Are Initializer Blocks?
Initializer blocks are blocks of code inside a class that execute automatically.
There are two types:
- Instance Initializer Block – Runs before the constructor every time an object is created.
- Static Initializer Block – Runs once when the class is loaded into memory.
1. Instance Initializer Block
• Declared using { } inside a class (without any modifier).
• Executes before the constructor.
• Runs every time an object is created.
• Useful for common initialization across constructors.
Example:
public class InstanceInitExample {
private String name;
// Instance initializer block
{
System.out.println(“Instance Initializer Block executed”);
name = “Default Name”;
}
public InstanceInitExample() {
System.out.println(“Constructor executed”);
}
public void display() {
System.out.println(“Name: ” + name);
}
public static void main(String[] args) {
InstanceInitExample obj1 = new InstanceInitExample();
obj1.display();
}
}
Output:
Instance Initializer Block executed
Constructor executed
Name: Default Name
2. Static Initializer Block
- Declared using static { } inside a class.
- Executes only once when the class is first loaded by the JVM.
- Used for initializing static variables or resources.
Example:
public class StaticInitExample {
private static int counter;
// Static initializer block
static {
System.out.println(“Static Initializer Block executed”);
counter = 100;
}
public static void showCounter() {
System.out.println(“Counter: ” + counter);
}
public static void main(String[] args) {
StaticInitExample.showCounter();
}
}
Output:
Static Initializer Block executed
Counter: 100
Execution Order of Initializers
When a class is executed:
- Static initializer blocks run (only once).
- Instance initializer blocks run (every time an object is created).
- Constructor executes.
Example:
public class InitOrderExample {
static {
System.out.println(“Static block”);
}
{
System.out.println(“Instance block”);
}
public InitOrderExample() {
System.out.println(“Constructor”);
}
public static void main(String[] args) {
new InitOrderExample();
new InitOrderExample();
}
}
Output:
Static block
Instance block
Constructor
Instance block
Constructor
Best Practices
- Use static initializer blocks for initializing static variables or resources (e.g., DB connections, configuration).
- Use instance initializer blocks to avoid duplicate code across constructors.
- Keep initializer blocks short and simple.
- Don’t overuse them—prefer constructors when possible for clarity.
Conclusion
Java Initializer Blocks provide a flexible way to set up classes and objects.
- Use static initializer blocks to run code once when a class is loaded.
- Use instance initializer blocks to run code every time an object is created, before the constructor.
By combining constructors and initializer blocks wisely, you can make your Java code more efficient and maintainable.
Example: Combining All Access Modifiers
package com.example;
public class AccessDemo {
public int pubVar = 1;
protected int protVar = 2;
int defaultVar = 3; // package-private
private int privVar = 4;
public void show() {
System.out.println(“Public: ” + pubVar);
System.out.println(“Protected: ” + protVar);
System.out.println(“Default: ” + defaultVar);
System.out.println(“Private: ” + privVar);
}
}
Best Practices
- Use private fields with getters/setters for encapsulation.
- Use public only when absolutely necessary.
- Use protected for inheritance-friendly designs.
- Prefer default for package-level utilities.
- Don’t overexpose class members—least privilege principle.
Conclusion
Access modifiers are a powerful tool in Java to control visibility and enforce encapsulation.
- Use private for sensitive fields.
- Use protected for inheritance.
- Use default for package-level access.
- Use public sparingly for APIs and widely used methods.
By mastering access modifiers, you’ll build secure, maintainable, and robust Java applications.