Problem
How can you safely call dynamically dispatched methods during object construction?
Context
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.
Solution
Separate object creation into two or more phases:
Use private/protected to force users of the class to call the factory method rather than using the new operator.
Resulting Context
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.
Related Patterns
An alternative approach is to TestWhetherInConstructionPhase in the body of methods invoked during construction.
-- NatPryce
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:
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.
-- HowardFear
Aside Question:
Any ideas "why" the JavaLanguage chose to dynamically dispatch in constructors? -- Gaurav
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, 2001-01-05
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.) -- JeffGrigg
Since this is statically checkable I assume it's not allowed.
This page mirrored in JavaIdioms as of April 29, 2006