In Java, is there a legitimate reason to call a non-final method from a class constructor?

There are times it can be very hard not to.

Take Joda Time, for example. Its Chronology type hierarchy is very deep, but the abstract AssembledChronology class is based on the idea that you assemble a bunch of "fields" (month-of-year etc). There's a non-final method, assembleFields, which is called during the constructor, in order to assemble the fields for that instance.

They can't be passed up the constructor chain, because some of the fields need to refer back to the chronology which creates them, later on - and you can't use this in a chained constructor argument.

I've gone to nasty lengths in Noda Time to avoid it actually being a virtual method call - but it's something remarkably similar, to be honest.

It's a good idea to avoid this sort of thing if you possibly can... but sometimes it's a real pain in the neck to do so, especially if you want your type to be immutable after construction.


One example is the non-final (and package-private) method HashMap#init(), an empty method which is in place for the exact purpose of being overriden by subclasses:

/**
 * Initialization hook for subclasses. This method is called
 * in all constructors and pseudo-constructors (clone, readObject)
 * after HashMap has been initialized but before any entries have
 * been inserted.  (In the absence of this method, readObject would
 * require explicit knowledge of subclasses.)
 */
void init() {
}

(from the HashMap source)

I don't have any examples of how it's used by subclasses - if anyone does, feel free to edit my answer.

EDIT: To respond to @John B's comment, I'm not saying it must be good design since it's used in the source. I just wanted to point out an example. I do notice that each HashMap constructor takes care to call init() last, but this is of course still before the subclass constructor. So an amount of responsibility is falling to the subclass implementation not to muck things up.


Generally, it's not good design to call methods on a class before it is constructed; however, Java allows exceptions in the case you know what you are doing (ie. you don't access uninitialized fields). With an abstract method, I don't think it is possible to "know" what you're doing in the parent class.

The above code can easily be solved by imposing stricter interpretation of "a class handles it's responsibilities." It's not the super class's responsibility to initialize the subclass, so it shouldn't be the super class's prerogative to call subclass code before such initialization might be complete.

Yes, it's done in the JDK (like the HashMap code) with special "init()" methods that imply initialization of all subclass code; but, I would offer that the following pattern of calls is much cleaner and permits more flexibility.

public class SSCCE {
    static abstract class A {
        public A() {

        }

        abstract void method();
    }

    static class B extends A {
        final String[] arr = new String[] { "foo", "bar" };

        public B() {
            super();
            method();
            System.out.println("In B(): " + Arrays.toString(arr));
        }

        void method() {
            System.out.println("In method(): " + Arrays.toString(arr));
        }
    }

    public static void main(String[] args) {
        new B().method();
    }
}

it just seems so much cleaner, in so many ways. Failing that, there's always the ability to construct your objects with proper "initialization sequence" through a Factory.