Always Explicitly Initialize Transient Fields Inside Marshalling Methods
The
transient
keyword is very useful when you’re writing
marshalling code. Very often, a first pass at making an object
implement the Serializable interface consists of
the following two steps:
Declare that the object implements the
Serializableinterface.Declare all the fields you don’t want to be serialized to be
transientvariables.
Many programmers will look at this and wonder if
it’s efficient enough. But very few will wonder
whether it’s correct. And the sad truth is that it
is often incorrect. The reason is that the
transient keyword really means
“Serialization shouldn’t pay
attention to this field at all.”[15] And that has serious
consequences when you combine it with the notion of
serialization’s extralinguistic constructor (as
discussed earlier). If you implement the
Serializable interface by following the previous
two methods, here’s what will happen when your
object is deserialized:
The instance will be created using the extralinguistic constructor (and hence, none of the initialization code in your constructors will be executed).
The serialization algorithm will completely ignore your transient fields.
The net result is that none of the transient fields will be initialized. This is rarely the expected outcome, and can result in bugs that are subtle and hard to track down.
The
SerializationTest class illustrates the problem in
detail. It has four integers (a,
b, c, and
d), which are initialized ...