What is the object field initialization and constructor order in Java
I ended the following scenario in the code earlier today (I admit it's a little strange, I've refactored it) When I run the unit test, I find that there is no field initialization when the superclass constructor runs I realize that I don't fully understand the order of constructor / field initialization, so I want someone to explain to me the order in which this happens
class Foo extends FooBase { String foo = "foobar"; @Override public void setup() { if (foo == null) { throw new RuntimeException("foo is null"); } super.setup(); } } class FooBase { public FooBase() { setup(); } public void setup() { } } @Test public void testFoo() { new Foo(); }
The abbreviations from JUnit go back as follows. I think I expect $foo< Init > set foo
$Foo.setup $FooBase.<init> $Foo.<init> .testFoo
Solution
Yes, in Java (for example, unlike C#), the field initializer is called after the super class constructor. This means that any overridden method call to the constructor will be called before executing the field initializer
The order is:
>Initialize the superclass (call these steps recursively) > execute the field initializer > execute the constructor body (which has occurred in step 1 after any constructor link)
Basically, calling non final methods in constructors is a bad idea. If you intend to do so, record it clearly so that anyone who overrides the method knows that the method will be called before executing the field initializer (or constructor body)
For details, see JLS section 12.5