Please verify my understanding/guess, why code below throws NPE and what exactly happens:
- After new Derived() constructor of Derived class called.
- Derived contructor immediately calls Base constructor (implicit constructor chaining happens)
- Base constructor calls foobar(). There is no different foobar() methods (Base version and Derived version), so this is foobar() in "version" as overridden in Derived.
- This single foobar() "version" (shared between Base\Derived) searches for str field to work with. As foobar() is overridden ("defined") in Derived, it needs str from Derived (it cannot use str from Base).
- At this moment str in Derived is not init (because until Base constructor finishes, Derived constructor cannot start working), so we get NPE.
P.S. I know that it is not recommended to call non-final or non-private, non-static methods from constructors. Besides, for virtual method in C++, its overridden version from Derived won't be called in Base contructor like in Java.
class Base {
String str = "abc";
Base() {
foobar();
}
void foobar() {
System.out.println(str.toUpperCase());
}
}
class Derived extends Base {
String str = "qwe";
Derived() {
foobar();
}
@Override
void foobar() {
System.out.println(str.toLowerCase());
}
}
public class My {
public static void main(String[] args) {
new Derived();
}
}
My own research shows that in those answers there was no same (shadowed) field variable (str), which adds to the confusion. answer1 answer2