I recently spent quite a few minutes debugging a problem in production code that in the end turned out to be caused by a class calling an abstract method in its constructor, and the subclass implementation of that method tried to use a subclass field that had not been initialized yet (An example that illustrates the point is included below)
While researching this, I stumbled across this question, and was intrigued by Jon Skeet's answer:
In general it's a bad idea to call a non-final method within a constructor for precisely this reason - the subclass constructor body won't have been executed yet, so you're effectively calling a method in an environment which hasn't been fully initialized.
This has me wondering, is there ever a legitimate reason to call a non-final or abstract method from a constructor? Or is it pretty much always a sign of bad design?
Example
public class SSCCE {
static abstract class A {
public A() {
method(); // Not good; field arr in B will be null at this point!
}
abstract void method();
}
static class B extends A {
final String[] arr = new String[] { "foo", "bar" };
public B() {
super();
System.out.println("In B(): " + Arrays.toString(arr));
}
void method() {
System.out.println("In method(): " + Arrays.toString(arr));
}
}
public static void main(String[] args) {
new B().method();
}
}
And here is expected output:
In method(): null
In B(): [foo, bar]
In method(): [foo, bar]
The problem, of course, is that in the first call to method()
the field arr
is null because it hasn't been initialized yet.