Static Block in Java: the Static Initialization Block Explained - Quiz
Total: 5 questions
1. What is a static block in Java, and why would you use it?
What is a static block in Java, and why would you use it?
A static block (static initialization block, static initializer) is a block of code declared as static { ... } directly in the class body, outside any method or constructor. It runs once, when the class is initialized — before main() and before the first object is created.
It is used when a static field cannot be set up with one simple assignment: filling a static collection or array in a loop, initialization that needs try-catch, one-time class setup (System.loadLibrary(...), reading configuration), or several dependent static fields. A class may have several static blocks; they run top to bottom together with static field initializers. For small immutable collections Java 9+ often replaces a static block with Map.of(...) or List.of(...).
2. When exactly does a static block run, and can it run more than once?
When exactly does a static block run, and can it run more than once?
A static block runs during class initialization, which is lazy — on the first active use of the class: new, a static method call (including main()), access to a static field, initialization of a subclass, or Class.forName("..."). Declaring a variable of the type, creating an array new Foo[10], the literal Foo.class, or reading a compile-time constant such as static final int MAX = 10; does not trigger it (a constant is inlined by the compiler; static final Integer MAX = 10; is not a compile-time constant and does trigger it).
A class is initialized once per classloader, so within one classloader the block never runs twice; the JVM also locks the class during initialization, so it is thread-safe. The same class loaded by two different classloaders runs its static block once for each. Since Java 7 a static block cannot replace main: the launcher checks for main before initializing the class.
3. What is the difference between a static block, an instance initializer block, and a constructor in Java?
What is the difference between a static block, an instance initializer block, and a constructor in Java?
A static block static { ... } runs once, when the class is initialized. It sees only static fields, has no this or super, and cannot throw checked exceptions.
An instance initializer block { ... } runs on every new — after super(...) and before the constructor body. It can use static and instance fields and this; the compiler copies it into every constructor that does not start with this(...). It is mostly used in anonymous classes, where a constructor cannot be declared.
A constructor can take parameters, and only the one matching the new call runs, while an initializer block takes no parameters and runs for whichever constructor is called.
4. In what order do static blocks, instance blocks, and constructors run when a subclass object is created?
In what order do static blocks, instance blocks, and constructors run when a subclass object is created?
For new Child() where Child extends Parent:
- Class initialization (only once): static fields and static blocks of
Parent, then ofChild, each in declaration order. - Object creation (on every
new): instance fields and instance blocks ofParent, then theParentconstructor body; then instance fields and instance blocks ofChild, then theChildconstructor body.
Result: Parent static → Child static → Parent instance block → Parent constructor → Child instance block → Child constructor. For the second object only step 2 is repeated — the classes are already initialized.
5. What happens if a static block throws an exception, and what other pitfalls does a static block have?
What happens if a static block throws an exception, and what other pitfalls does a static block have?
A static block cannot throw a checked exception — it must be caught inside with try-catch, otherwise the code does not compile. If an unchecked exception escapes a static block or a static field initializer (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 for as long as its classloader lives.
Other pitfalls: an illegal forward reference — a static block may assign to a field declared below it, but cannot read it by its simple name; no this, super, or direct access to instance members; heavy logic slows down the first use of the class and is hard to test. The "double brace initialization" idiom new HashMap<>() {{ put("a", 1); }} is an anonymous subclass with an instance block and is considered an antipattern.