This is one of several JavaIdioms
on the WikiWikiWeb
How can you safely call dynamically dispatched methods during object construction?
Java dynamically dispatches methods based on the full type of the object, even when the object is not fully constructed. This means that a method that is defined by the derived class, and expects some invariant to hold over the state of the derived class, can be called before that invariant is set up.
Separate object creation into two or more phases:
- Allocate the object and initialise it to some safe state in the constructor.
- Call dynamically dispatched methods to set the state of the object to hold values required by the caller.
Encapsulate this multi-phase construction within a static method or a factory.
Use private/protected to force users of the class to call the factory method rather than using the new
Objects cannot be created in an invalid state.
Dynamically dispatched methods never see the object in an invalid state.
Objects cannot be created by the Class.newInstance method or serialised if the default constructor is private or protected.
An alternative approach is to TestWhetherInConstructionPhase
in the body of methods invoked during construction.
A strategy I've used a couple of times (not quite enough to be a pattern)
is something I call OneTimeConstructor?
. There are two parts to it:
- Define a constructor interface for the object. Implement the interface as an inner class of the object being constructed so the it can set private variables without exposing public setters.
- Use a private variable to hold the constructor. Implement a getConstructor() method which returns the variable and reset it to null.
This allows me to keep the private data private and ensure that the
object is only 'constructed' once.
Depending on the complexity of the construction, I've also used an
abstract class instead of an interface. This becomes something like
a strategy class with the inner class implementing only setters.
This allows me to separate the construction complexity from the
operational characteristics of the object.
Any ideas "why" the JavaLanguage
chose to dynamically dispatch in constructors?
I'd guess this follows the PrincipleOfLeastSurprise
. Why should a method called in a Constructor work different than when called somewhere else?
Another interesting question in this direction might be "Why are all
functions in the JavaLanguage
have to be dynamically dispatched?" ... Wait. final
just does this. It's only well hidden. -- DavidSchmitt
C++ takes the opposite choice:
In the constructor of the superclass, if you call virtual methods, you won't get child class implementations, you'll get your own.
Yes, that means that the vtable (virtual function table pointer), and hence the class of the object, changes several times during the construction of an object.
(I've often wondered what happens when the superclass calls its own pure virtual functions during construction. Undefined probably -- which would typically be a crash.)
Since this is statically checkable I assume it's not allowed.