I came across a interesting gotcha involving Java class initialization. Consider the following:
abstract class Base {
Base() {
inner();
}
protected abstract void inner();
}
public class Derived extends Base {
int x = 0; // GOTCHA!
int y;
Derived() {
System.out.format("x = %s, y = %s\n", x, y);
}
@Override
protected void inner() {
x = 666;
y = 777;
}
public static void main(String[] args) {
new Derived();
}
}
The program prints out "x = 0, y = 777". You might have expected x to be 666. The culprit is the field initializer labelled GOTCHA! which is executed after the superclass' constructor. Java takes great pains to prevent you from writing code like this (e.g. you cannot reference this when calling the super() constructor). And this example shows why. This is all made clear in the Java Language Specification, but here is a practical instance that actually occurred in the field.