What is object field initialization and constructor order in Java

I ended up the following scenario in code earlier today (which I admit is kinda weird and I have since refactored). When I ran my unit test I found that a field initialization was not set by the time that the superclass constructor has run. I realized that I do not fully understand the order of constructor / field initialization, so I am posting in the hopes that someone explain to me the order in which these occur.

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 abbreviated backtrace from JUnit is as follows, I guess I expected $Foo.<init> to set foo.

$Foo.setup
$FooBase.<init>
$Foo.<init>
.testFoo
Jon Skeet
people
quotationmark

Yes, in Java (unlike C#, for example) field initializers are called after the superclass constructor. Which means that any overridden method calls from the constructor will be called before the field initializers are executed.

The ordering is:

  • Initialize superclass (recursively invoke these steps)
  • Execute field initializers
  • Execute constructor body (after any constructor chaining, which has already taken place in step 1)

Basically, it's a bad idea to call non-final methods in constructors. If you're going to do so, document it very clearly so that anyone overriding the method knows that the method will be called before the field initializers (or constructor body) are executed.

See JLS section 12.5 for more details.

people

See more on this question at Stackoverflow