I'm having trouble understanding initialization order when a class has a static instance of itself. Also, why this behavior seems to be different for a String
.
Please see the following example:
public class StaticCheck {
private static StaticCheck INSTANCE = new StaticCheck();
private static final List<String> list =
new ArrayList<String>(Arrays.asList("hello"));
private static final Map<String, String> map =
new HashMap<String, String>();
private static final String name = "hello";
public static StaticCheck getInstance() {
return INSTANCE;
}
private StaticCheck() {
load();
}
private void load() {
if(list != null) {
System.out.println("list is nonnull");
} else {
System.out.println("List is null");
}
if(name != null) {
System.out.println("name is nonnull");
} else {
System.out.println("name is null");
}
if(map != null) {
System.out.println("Map is nonnull");
} else {
System.out.println("Map is null");
}
}
public static void main(String[] args) {
StaticCheck check = StaticCheck.getInstance();
}
}
Output:
List is null
name is nonnull
Map is null
I am absolutely not clear on why the field name
is not null.
Static fields are initialized in the following cases as mentioned under Class initialization:
http://javarevisited.blogspot.in/2012/07/when-class-loading-initialization-java-example.html
Looking into the above example, my thoughts:
As said, static fields are initialized before instance initialization in Java. Here, when I am invoking the static method getInstance()
, it will lead to class initialization which implies initialization of static fields. In this case, the fields map
and and list
shouldn't be null.
In the above example, since the field INSTANCE
is static, its object initialization takes place and its constructor calls load()
when other fields were not initialized. Because of this the fields list
and map
are null. So then why did name
get initialized? I am a little confused.
The String
type name
variable is a compile time constant, which are inlined by the compiler at compile time. So, the condition:
if (name != null)
after compilation will become:
if ("hello" != null)
which is of course true.
As for why map
and list
are null
, that's because, when the class is initialized, INSTANCE
field is initialized, calling the constructor, which in turn calls the load()
method. Note that, by this time, the other static
initializers has not yet been run. So, map
and list
are still null
. So, printing them in load()
method will be null
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With