The Java serialization spec for Java 1.5 said:
For serializable objects, the no-arg constructor for the first
non-serializable supertype is run. For serializable classes, the
fields are initialized to the default value appropriate for its type.
Then the fields of each class are restored by calling class-specific
readObject methods, or if these are not defined, by calling the
defaultReadObject method. Note that field initializers and
constructors are not executed for serializable classes during
deserialization.
However, this means if we put a static variable (for example a counter variable) inside the class, it will not be updated as normally would:
class Foo {
static int t;
public Foo() {
t++;
}
}
public class Bar extends Foo implements Serializable {
static int t;
public Bar() {
t++;
}
}
In this case, if one instance of Bar
is deserialized, then the counter for Foo
is correct and the counter for Bar
is off-by-one.
I wonder why does deserialization does not invoke the constructor? Since it seems that while this will gain a bit on speed, it can cause potential problems. The compiler could be easily designed to produce a "static constructor" that only updates the static variables that will be updated and does not rely on outside information when the class is loaded.
Also, I wonder what is the best way to avoid this? The solution I can think of is packing the deserialization with the operation on the static variable.
Thanks for any inputs in advance!
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…