Deserializing serializable Java objects without a default constructor

I’ve spent the past few days implementing a serialisation process overriding the ObjectOutputStream and ObjectInputStream classes. However there seemed to be certain classes that cannot be deserialized even though they are serializable, as they have no default constructor.

The serialisation class documentation implies that the constructor for a serializable class isn’t called anyway, which makes sense as you don’t really want to set up a class from scratch when you are deserializing, just restore it.

Most replies to questions on this subject seemed to imply that it can’t be done except by the default serialization classes. This is no use if you want to override these, and since they are overridable, surely Sun woudn’t have made it impossible.

One hit during my search mentioned the ReflectionFactory class in passing, but didn’t have any detail, so I looked into it further, and sure enough, this seems to be the answer.

The Solution?

It would seem that the ReflectionFactory class can create a Constructor object on the fly, using the default constructor of the first non-serializable superclass, and the class you’re trying to instanciate.

So when overriding the deserialisation process, you can create an instance of an object that doesn’t use the default constructor, and doesn’t need one to exist by calling the constructor returned by something like the following:

ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
Class type = HashMap.class; //
Class nonSerType;
for ( nonSerType = type; Serializable.class.isAssignableFrom(nonSerType); nonSerType = nonSerType.getSuperclass() ) {}
Constructor superCon, deSerCon;
superCon = nonSerType.getConstructor();
deSerCon = rf.newConstructorForSerialization(type, superCon);

where the deSerCon can be used to instanciate the deserialized object.

This process seems to work for my deserialization work, and so I’ve documented it here. I’ll admit, I’ve no idea if there are any specific limitations to this process, but for the limited range of classes I’ve tested so far, it works fine.