I am wondering when static variables are initialized to their default values. Is it correct that when a class is loaded, static vars are created (allocated), then static initializers and initializations in declarations are executed? At what point are the default values are given? This leads to the problem of forward reference.
Also please if you can explain this in reference to the question asked on Why static fields are not initialized in time? and especially the answer given by Kevin Brock on the same site. I can't understand the 3rd point.
This question is related to
java
static
initialization
Static fields are initialized when the class is loaded by the class loader. Default values are assigned at this time. This is done in the order than they appear in the source code.
The order of initialization is:
The details of the process are explained in the JVM specification document.
The static variable can be intialize in the following three ways as follow choose any one you like
or you can do by making static block eg:
static {
// whatever code is needed for initialization goes here
}
There is an alternative to static blocks — you can write a private static method
class name {
public static varType myVar = initializeVar();
private static varType initializeVar() {
// initialization code goes here
}
}
See:
The last in particular provides detailed initialization steps that spell out when static variables are initialized, and in what order (with the caveat that final
class variables and interface fields that are compile-time constants are initialized first.)
I'm not sure what your specific question about point 3 (assuming you mean the nested one?) is. The detailed sequence states this would be a recursive initialization request so it will continue initialization.
Starting with the code from the other question:
class MyClass {
private static MyClass myClass = new MyClass();
private static final Object obj = new Object();
public MyClass() {
System.out.println(obj); // will print null once
}
}
A reference to this class will start initialization. First, the class will be marked as initialized. Then the first static field will be initialized with a new instance of MyClass(). Note that myClass is immediately given a reference to a blank MyClass instance. The space is there, but all values are null. The constructor is now executed and prints obj
, which is null.
Now back to initializing the class: obj
is made a reference to a new real object, and we're done.
If this was set off by a statement like: MyClass mc = new MyClass();
space for a new MyClass instance is again allocated (and the reference placed in mc
). The constructor is again executed and again prints obj
, which now is not null.
The real trick here is that when you use new
, as in WhatEverItIs weii = new WhatEverItIs( p1, p2 );
weii
is immediately given a reference to a bit of nulled memory. The JVM will then go on to initialize values and run the constructor. But if you somehow reference weii
before it does so--by referencing it from another thread or or by referencing from the class initialization, for instance--you are looking at a class instance filled with null values.
Source: Stackoverflow.com