Deserialized object has null in all fields
I have written my Container<T>
class which backups its T
items in several collections -- primary one is List<T>
, others are various maps with data derived from items, mostly for optimized search.
Class looks like this:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private final Map<...> m开发者_运维百科ap1 = Maps.newHashMap();
private final Map<...> map2 = Maps.newHashMap();
}
Standard serialization works like a charm, but maps do not need to be serialized. I tried to set maps as transient
and use readObject()
in this way:
class Container<T> implements Serializable {
private static final long serialVersionUID = 1L;
private final List<T> items = Lists.newArrayList();
private transient Map<...> map1;
private transient Map<...> map2;
public Container() {
initContainer();
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
initContainer();
}
private void initContainer() {
map1 = Maps.newHashMap();
map2 = Maps.newHashMap();
// prepare data in maps
for (T item: items) {
map1.put(...);
map2.put(...);
}
}
}
Simple test with ObjectOutputStream.writeObject()
and ObjectInputStream.readObject()
again works. But when I integrate Container
to real application where is this class serialized and deserialized as a part of other complex classes (Wicket Page in fact), strange things happens.
I did some debugging and here are my findings:
- serialization of
Container
with (n) items has done OK - deserialization of
Container
has done OK - deserialization of each
T
item is called only (n-1) times (by counting calls to itsreadObject()
method) - in
containerInit()
hadList<T>
correct (n) number of items, but one of them (that one for which is not called deserialization) is in very strange state - all fields havenull
value - and my code here throws NPE
Questions:
- What state has that strange object after deserialization (it is existing but without
readObject()
call and with null in all fields)? - Maybe deserialization of that strange object is not completed, but I have read that reading objects from
ObjectInputStream
is blocking, so all objects in my list must be in correct state. Or I something overlooked? - Are there any technique/tool/practice for catching things like this?
Thank you.
As I wrote in comment the problem was in touching items in serialized collection during Container.readObject()
. Some of these objects had in this moment null fields. When I postponed their touching outside deserialization of Container
, these objects had correct field values.
My hypothesis:
Lets have object parent with field collection of other objects children. Both parent and children are serializable, as well as collection. During customized parent deserialization in readObject()
method aren't children fully accessible, they exists but its deserialization is not complete. You have to access children only after parent deserialization is processed.
This hypothesis works for me, but I still don't know why.
精彩评论