In Java, deserializing a class does not invoke its constructor. Some initializations affect more than just instance variables.
Therefore, create a separate private helper method called "emerge" which takes no parameters (but may access instance variables) for all changes to non-instance variables (such as thread activation, object registration, or static variable updates). Call this method from the constructor(s) and readObject, if defined.
(Inspired by comments by RobEnglander? at SIGS Java conference, Sept 1997)
Notes: is "emerge" a good name for this method? How about "announcePresence"? Should all non-serializable (and transient) instance variables be initialized here? Suggest so.
Consequence: a class that needs such a method should not use default serialization.
-- RussellGold
I like the idea of breaking out a "postInitialize()" method (which I think is more general than "emerge()") from the Constructor so that it can also be called from the readObject() to initialize transient variables and do thread starts, event registration,etc. Good idea. -- KyleBrown
I'm not crazy about the name "postInitialize" because I want the method name to describe what it does, rather than when it is called; however, I agree that it is better than "emerge." -- RussellGold
How about "initializeInContext()"? -- LeeDanielCrocker?
Wht not just "initialize"?
Can I define readObject and writeObject, and have readObject call emerge() after it unserializes the object (presumably using defaultReadObject)? What I am getting at is, what are the forces behind this pattern? Is it for when you need exact control over when the object emerges?
There is such constructs in EJB, and it is named "activate" and "passivate". passivate() is called just before the object is written into the Database (which is equivalent to "serialize") and activate() is called just after it is read from the database (equivalent to deserialize).
The word "passivate" is just wrong.
In ARM/SymbianOs C++ a similar approach is mandatory for any class that (an instance of) owns resources on the heap. Since heap allocation can fail, and since in this dialect there is no way for a constructor to indicate failure beyond panicking the OS kernel, any class that owns heap allocated objects must have a "second stage constructor", by convention called ConstructL() to do that allocation.