Team LiB
Previous Section Next Section

5.14. Object Persistence

The Java platform provides two mechanisms for object persistence: the ability to save object state so that the object can later be recreated. Both mechanisms involve serialization; the second is aimed particularly at JavaBeans.

5.14.1. Serialization

One of the most important features of the java.io package is the ability to serialize objects: to convert an object into a stream of bytes that can later be deserialized back into a copy of the original object. The following code shows how to use serialization to save an object to a file and later read it back:

Object o;  // The object we are serializing; it must implement Serializable
File f;    // The file we are saving it to

try {
  // Serialize the object
  ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
  oos.writeObject(o);
  oos.close();

  // Read the object back in
  ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
  Object copy = ois.readObject();
  ois.close();
} 
catch (IOException e) { /* Handle input/output exceptions */ }
catch (ClassNotFoundException cnfe) { /* readObject() can throw this */ }

The previous example serializes to a file, but remember, you can write serialized objects to any type of stream. Thus, you can write an object to a byte array, then read it back from the byte array, creating a deep copy of the object. You can write the object's bytes to a compression stream or even write the bytes to a stream connected across a network to another program!

5.14.2. JavaBeans Persistence

Java 1.4 introduced a serialization mechanism intended for use with JavaBeans components. java.io serialization works by saving the state of the internal fields of an object. java.beans persistence, on the other hand, works by saving a bean's state as a sequence of calls to the public methods defined by the class. Since it is based on the public API rather than on the internal state, the JavaBeans persistence mechanism allows interoperability between different implementations of the same API, handles version skew more robustly, and is suitable for longer-term storage of serialized objects.

A bean and any descendant beans or other objects that are serialized with java.beans.XMLEncoder can be deserialized with java.beans.XMLDecoder. These classes write to and read from specified streams, but they are not stream classes themselves. Here is how you might encode a bean:

// Create a JavaBean, and set some properties on it
javax.swing.JFrame bean = new javax.swing.JFrame("PersistBean");
bean.setSize(300, 300);
// Now save its encoded form to the file bean.xml
BufferedOutputStream out =                 // Create an output stream
    new BufferedOutputStream(new FileOutputStream("bean.xml"));
XMLEncoder encoder = new XMLEncoder(out);  // Create encoder for stream
encoder.writeObject(bean);                 // Encode the bean
encoder.close();                           // Close encoder and stream

Here is the corresponding code to decode the bean from its serialized form:

BufferedInputStream in =                   // Create input stream
    new BufferedInputStream(new FileInputStream("bean.xml"));
XMLDecoder decoder = new XMLDecoder(in);   // Create decoder for stream
Object b = decoder.readObject();           // Decode a bean
decoder.close();                           // Close decoder and stream
bean = (javax.swing.JFrame) b;             // Cast bean to proper type
bean.setVisible(true);                     // Start using it

    Team LiB
    Previous Section Next Section