How ObjectInputStream.readObject Works

R

Roedy Green

I have been poking around inside ObjectInputStream and related
classes. I think I have a pretty good handle now on how readObject
performs its magic.

The following is quoted from

http://mindprod.com/jgloss/serialization.html#READOBJECT

At first glance, readObject seems to have magical properties of being
able to create and initialise arbitrary Objects.
java.util.ObjectInputStream. readObject uses ObjectStreamClass.
newInstance() to create an empty shell of an Object later filled in
with the read. ObjectStreamClass.newInstance creates a new instance of
the represented class. If the class is Externalizable, it invokes its
public no-arg constructor; otherwise, if the class is Serializable, it
invokes the no-arg constructor of the first non-serializable
superclass.

This means the code in the outer layers of constructor of a
Serializable Object will not be invoked, but the inner core, e.g. the
Object root constructor code will be. In effect, the constructor is
not called. It also means Serializable Objects don't need a no-arg
constructor. This short-circuited constructor call is why you must
manually initialise reconstituted transient fields that would normally
be handled by the constructor. The advantage of not calling the
constructor is efficiency. Most of its work will be soon overridden by
data from the stream.

Externalizable Objects on the other hand must have a no-arg
constructor, and it will be called when that Object is reconstituted,
before any of the stream data is read.

Then how does readObject take the stream of bytes from the stream and
put them in the proper spots in the Object? It does not just do a byte
block move. The first time a class is encountered in the object
stream, serialization uses reflection to build a table for that class
of all its fields, types and their JVM virtual machine offsets.
readObject uses ObjectStreamClass. setPrimFieldValues that uses the
table to field by field copy the bytes into the proper slots in the
newly created Object. This is clearly a much more CPU intensive
operation that reading a C++ struct or a nio buffer read.

You might think most of this code would have to be native, but it is
not. The only code that has to be native in the code that converts JVM
offsets into internal byte offsets for the store. The rest is all
platform independent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top