Serialization
Serialization is the process of writing the
state of an object to a byte stream. This is useful when you want to save the state of your program to a persistent
storage area, such as a file. At a later time, you may restore these objects by
using the process of deserialization.
Serialization
is also needed to implement Remote Method
Invocation (RMI). RMI allows a Java object on one machine to invoke a
method of a Java object on a different machine. An object may be supplied as an
argument to that remote method. The sending machine serializes the object and
transmits it. The receiving machine deserializes it. (More information about
RMI appears in Chapter 30.)
Assume
that an object to be serialized has references to other objects, which, in
turn, have references to still more objects. This set of objects and the
relationships among them form a directed graph. There may also be circular
references within this object graph. That is, object X may contain a reference
to object Y, and object Y may contain a reference back to object X. Objects may
also contain references to themselves. The object serialization and
deserialization facilities have been designed to work correctly in these
scenarios. If you attempt to serialize an object at the top of an object graph,
all of the other referenced objects are recursively located and serialized.
Similarly, during the process of deserialization, all of these objects and
their references are correctly restored.
An
overview of the interfaces and classes that support serialization follows.
Serializable
Only an
object that implements the Serializable
interface can be saved and restored by the serialization facilities. The Serializable interface defines no
members. It is simply used to indicate that a class may be serialized. If a
class is serializable, all of its subclasses are also serializable.
Variables
that are declared as transient are
not saved by the serialization facilities. Also, static variables are not saved.
Externalizable
The Java
facilities for serialization and deserialization have been designed so that
much of the work to save and restore the state of an object occurs
automatically. However, there are cases in which the programmer may need to
have control over these processes. For example, it may be desirable to use
compression or encryption techniques. The Externalizable
interface is designed for these situations.
The Externalizable interface defines these
two methods:
void readExternal(ObjectInput inStream) throws IOException, ClassNotFoundException
void writeExternal(ObjectOutput outStream) throws IOException
In these
methods, inStream is the byte stream
from which the object is to be read, and outStream
is the byte stream to which the object is to be written.
ObjectOutput
The ObjectOutput interface extends the DataOutput and AutoCloseable interfaces and supports object serialization. It
defines the methods shown in Table 20-6. Note especially the writeObject( ) method. This is called
to serialize an object. All of these methods will throw an IOException on error conditions.
ObjectOutputStream
The ObjectOutputStream class extends the OutputStream class and implements the ObjectOutput interface. It is
responsible for writing objects to a stream. One constructor of this class is shown here:
ObjectOutputStream(OutputStream
outStream) throws IOException
The
argument outStream is the output
stream to which serialized objects will be written. Closing an ObjectOutputStream automatically closes
the underlying stream specified by outStream.
Several
commonly used methods in this class are shown in Table 20-7. They will throw an
IOException on error conditions.
There is also an inner class to ObjectOuputStream
called PutField. It facilitates the
writing of persistent fields, and its use is beyond the scope of this book.
ObjectInput
The ObjectInput interface extends the DataInput and AutoCloseable interfaces and defines the methods shown in Table
20-8. It supports object serialization. Note especially the readObject( ) method. This is called to
deserialize an object. All of these methods will throw an IOException on error conditions. The readObject( ) method can also throw
ClassNotFoundException.
ObjectInputStream
The ObjectInputStream class extends the InputStream class and implements the ObjectInput interface. ObjectInputStream is responsible for
reading objects from a stream. One constructor of this class is shown here:
ObjectInputStream(InputStream
inStream) throws IOException
The
argument inStream is the input stream
from which serialized objects should be read. Closing an ObjectInputStream automatically closes the underlying stream
specified by inStream.
Several commonly used methods in this class are shown in Table 20-9. They will throw an IOException on error conditions. The readObject( ) method can also throw ClassNotFoundException. There is also an inner class to ObjectInputStream called GetField. It facilitates the reading of persistent fields, and its use is beyond the scope of this book.
A Serialization Example
The following program illustrates how to use object serialization and deserialization. It begins by instantiating an object of class MyClass. This object has three instance variables that are of types String, int, and double. This is the information we want to save and restore.
A FileOutputStream is created that refers to a file named "serial", and an ObjectOutputStream is created for that file stream. The writeObject( ) method of ObjectOutputStream is then used to serialize our object. The object output stream is flushed and closed.
A FileInputStream is then created that refers to the file named "serial", and an ObjectInputStream is created for that file stream. The readObject( ) method of ObjectInputStream is then used to deserialize our object. The object input stream is then closed.
Note
that MyClass is defined to implement
the Serializable interface. If this
is not done, a NotSerializableException
is thrown. Try experimenting with this program by declaring some of the MyClass instance variables to be transient. That data is then not saved
during serialization.
//A serialization demo.
//This program uses try-with-resources. It
requires JDK 7 or later.
import java.io.*;
public class
SerializationDemo {
public static void
main(String args[]) {
// Object serialization
try ( ObjectOutputStream
objOStrm =
new ObjectOutputStream(new
FileOutputStream("serial")) )
{
MyClass object1 = new
MyClass("Hello", -7, 2.7e10); System.out.println("object1:
" + object1);
objOStrm.writeObject(object1);
}
catch(IOException e) {
System.out.println("Exception
during serialization: " + e);
}
// Object deserialization
try ( ObjectInputStream
objIStrm =
new ObjectInputStream(new
FileInputStream("serial")) )
{
MyClass object2 =
(MyClass)objIStrm.readObject(); System.out.println("object2: " +
object2);
}
catch(Exception e) {
System.out.println("Exception
during deserialization: " + e);
}
}
}
class MyClass implements
Serializable { String s;
int i; double d;
public MyClass(String s, int
i, double d) { this.s = s;
this.i = i; this.d = d;
public String toString() {
return "s=" + s +
"; i=" + i + "; d=" + d;
}
}
This
program demonstrates that the instance variables of object1 and object2 are
identical. The output is shown here:
object1: s=Hello; i=-7;
d=2.7E10 object2: s=Hello; i=-7; d=2.7E10
Related Topics
Privacy Policy, Terms and Conditions, DMCA Policy and Compliant
Copyright © 2018-2023 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.