Monday, July 2nd, 2007

Java constructors, static initalizers and the Template pattern

159 words

Alrighty then, I fell into a trap, I looked for other people warning about it, and I found none, so I’m doing it myself.

What does this Java do?

public abstract class SuperClass {

    public SuperClass() {
        setup();
    }

    public abstract void setup();
}

public class SubClass extends SuperClass {
    public String status = "uninitialised";
    // If this was omitted, the default constructor would be the same anyway
    public SubClass() {
        super();
    }

    // Remember, super() calls setup()
    public void setup() {
        status = "initialised";
    }

    public static void main(String[] args) {
        SubClass obj = new SubClass();
        // So, what does this output?
        System.out.println(obj.status);
    }
}

I think it looks as if it ought to print “initialised”: the code provides a default value for the “status” field, the constructor runs the parent’s contructor, which itself calls setup(), which changes “status” to “initialised”.

However, it doesn’t. It prints “uninitialised”. Why?

Static initialisers get called *after* any superclass constructors.

Hence:

public String status = "uninitialised";
public SubClass() {
    super();
}

… is equivalent to:

public String status;
public SubClass() {
    super();
    status = "uninitialised";
}

Ouch! Still now I know, and so do you, so we can avoid it.

Leave a Reply



Spam Karma 2 has sent 63602 comments to hell and 182 comments to purgatory. The total spam karma of this blog is -33434. What's your karma?