Reputation: 11514
When are static fields initialized? If I never instantiate a class, but I access a static field, are ALL the static blocks and private static methods used to instantiate private static fields called (in order) at that instant?
What if I call a static method? Does it also run all the static blocks? Before the method?
Upvotes: 127
Views: 80822
Reputation: 718698
A class's static initialization normally happens immediately before the first time one of the following events occur:
See JLS 12.4.1.
It is also possible to force a class to initialize (if it hasn't already initialized) by using Class.forName(fqn, true, classLoader)
or the short form Class.forName(fqn)
When does static class initialization happen?
See above.
When are static fields initialized?
As part of static class initialization; see above.
If I never instantiate a class, but I access a static field, are ALL the static blocks and private static methods used to instantiate private static fields called (in order) at that instant?
Yes. (Modulo that nothing is truly instantaneous.)
What if I call a static method? Does it also run all the static blocks? Before the method?
Yes and yes.
Note that it is possible to construct code where you can observe the default initialized value of a static field.
1 - The final bullet point was present in the JLS for Java 6 through Java 8, but it was apparently a mistake in the specification. It was finally corrected in the Java 9 JLS: see source.
Upvotes: 169
Reputation: 24472
Static fields are initialized during the initialization "phase" of the class loading (loading, linking and initialization) that includes static initializers and initializations of its static fields. The static initializers are executed in a textual order as defined in the class.
Consider the example:
public class Test {
static String sayHello() {
return a;
}
static String b = sayHello(); // a static method is called to assign value to b.
// but its a has not been initialized yet.
static String a = "hello";
static String c = sayHello(); // assignes "hello" to variable c
public static void main(String[] arg) throws Throwable {
System.out.println(Test.b); // prints null
System.out.println(Test.sayHello()); // prints "hello"
}
}
The Test.b prints null
because when the sayHello
was called in static scope, the static variable a
was not initialized.
Upvotes: 17
Reputation: 67986
Yes, all static initializers are run before you access class first time. If it was any other way, I would call it a bug.
Upvotes: 1