When working on my company's legacy code, I encountered an NPE during runtime. After debugging it, this is what I encountered :
public class ConcreteClass extends PreConcreteClass{
private List<Object> internalDS = new ArrayList<>();
public ConcreteClass() {
super();
....
}
@Override
protected void update() {
....
for(Object o : internalDS) {
...
}
...
}
public class PreConcreteClass extends AbstractClass{
......
public PreConcreteClass() {
super();
......
}
......
}
protected abstract class AbstractClass {
protected AbstractClass() {
.....
update();
....
}
protected void update() {
.....
}
}
The NPE was thrown when the overriding update method of the ConcreteClass was invoked, after the invocation of super from ConcreteClass and super from PreConcreteClass. The cause was internalDS - it was null, causing the for loop to threw the NPE.
First - this is against what I have always expected - that class fields which have been initialized at declaration are initialized before executing the constructor's scope. Is this not the case when calling the constructors of derived classes via super ?
Second - I solved the NPE by adding an init method which is called by the AbstractClass constructor, which is given an empty implementation by AbstractClass, and is overridden by the ConcreteClass with the initialization on internalDS.
I looked up some general advise in stack overflow. I had some discussions with my colleagues at work where we agreed that there is an inherit problem with the design above which caused the NPE. Since this is legacy code which we do not want to drastically change, I waned to know if anyone has a better alternative to the init method solution I used. Note - there are multiple constructors for each class.