There are four ways that a field can be initialized in Java. These are, in order:
- As part of a static initializer block
- As part of an instance initializer block
- Default value in declaration.
- In the constructor.
Used when a static field needs to be initialized to a more complex value than can be expressed in a single line.
public class Example {
private static int x;
// static initializer block
static {
int prev = 1;
x = 1;
for (int i = 2; i < 100; i++) {
prev = x;
x = (x + prev);
}
// x initialized to the 100th Fibonacci number
}
}Same purpose as the static initializer block, but for instance fields.
public class Example {
private int x;
// instance inititalizer block
{
String s = "The quick brown fox jumps over the lazy dog.");
String s = "The quick brown fox jumps over the lazy dog.";
Map<Character, Integer> chars = new HashMap<>();
for(char c : s.toCharArray()) {
if (chars.containsKey(c)) {
chars.put(c, chars.get(c) + 1);
} else {
chars.put(c, 1);
}
}
x = chars.size(); // the number of distinct characters in s (29, in this case)
}
}A common practice, these initializations, while defined in the field declaration are, when compiled, prepended to the constructor method itself.
public class Example {
private int x = 3;
}Meaning that the above declaration is, in most cases, equivalent to...
public class Example {
private int x;
public Example() {
x = 3;
}
}However, in the edge case demonstrated in this gist, a subclass declares a private instance variable that is referred to in its implementation of an abstract method declared in its superclass... and the supercalass calls that method from its own constructor. Meaning that the default value of a local field may appear to be applied later than anticipated.
The expected output of this gist is, in fact:
Superclass static initializer block
Subclass static initializer block
Superclass instance initializer block
Superclass constructor
Subclass implementation of method(), called by Superclass constructor
x = 0
Subclass instance initializer block
Subclass constructor
Subclass implementation of method(), called by main()
x = 1