THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

20.8. Object Serialization


The ability to save objects in a byte stream that can be transferred across the network (perhaps for use in
remote method invocations), saved to disk in a file or database, and later reconstituted to form a live object, is
an essential aspect of many real-world applications.


The process of converting an object's representation into a stream of bytes is known as serialization, while
reconstituting an object from a byte stream is deserialization. When talking about the classes, interfaces, and
language features involved in this overall process, we generally just use the term serialization and understand
that it includes deserialization as well.


A number of classes and interfaces are involved with serialization. You have already learned about the basic
mechanisms for reading and writing primitive types and strings using the Data stream classes (see page 537).
This section covers the object byte streamsObjectInputStream and ObjectOutputStreamthat allow
you to serialize and deserialize complete objects. Various other classes and interfaces provide specific support
for the serialization process. In addition, the field modifier TRansient provides a language-level means of
marking data that should not be serialized.


20.8.1. The Object Byte Streams


The Object streamsObjectInputStream and ObjectOutputStreamallow you to read and write
object graphs in addition to the well-known types (primitives, strings, and arrays). By "object graph" we mean
that when you use writeObject to write an object to an ObjectOutputStream, bytes representing the
objectincluding all other objects that it referencesare written to the stream. This process of transforming an
object into a stream of bytes is called serialization. Because the serialized form is expressed in bytes, not
characters, the Object streams have no Reader or Writer forms.


When bytes encoding a serialized graph of objects are read by the method readObject of
ObjectInputStreamthat is, deserializedthe result is a graph of objects equivalent to the input graph.


Suppose, for example, that you have a HashMap object that you wish to store into a file for future use. You
could write the graph of objects that starts with the hash map this way:


FileOutputStream fileOut = new FileOutputStream("tab");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
HashMap<?,?> hash = getHashMap();
out.writeObject(hash);


As you can see, this approach is quite straightforward. The single writeObject on hash writes the entire
contents of the hash map, including all entries, all the objects that the entries refer to, and so on, until the
entire graph of interconnected objects has been visited. A new copy of the hash map could be reconstituted
from the serialized bytes:


FileInputStream fileIn = new FileInputStream("tab");
ObjectInputStream in = new ObjectInputStream(fileIn);
HashMap<?,?> newHash = (HashMap<?,?>) in.readObject();


Serialization preserves the integrity of the graph itself. Suppose, for example, that in a serialized hash map, an
object was stored under two different keys:

Free download pdf