Zat Home
Documentation | JavaBeans | Requirements

Bean Requirements

To qualify as a bean, a java class must meet two requirements: construction and serialization.

Construction

Every bean must have a null (no-argument) constructor. You should use this constructor to initialize the bean with sensible defaults.

From the MyLine example bean:

Serialization

Serialization is the conversion of a java object in memory into a form that can be written to a disk or other device. To be serializable, a class must implement either java.io.Serializable or java.io.Externalizable.

The Serializable interface defines no methods; it is just a marker to indicate that a class can be written out. Thus, it's up to the programmer to make certain that a bean will serialize successfully. A class which fails to serialize will cause an exception whenever a bean tool (read: Spin) attempts to duplicate or save an instance of the class to disk, and will therefore be unusable as a bean.

The serialization process is recursive. When an object is serialized, each of its non-transient instance variables is serialized along with it. A variable is transient if it is declared with the transient keyword:

Transient variables are not saved when a bean is serialized. This means that when the bean is later deserialized, the values of all of its transient variables will be null. See the section on Deserialization for more information.

If a bean contains non-transient instance variables that contain non-primitive objects (i.e., they derive from java.lang.Object), each of the instance variables contained in each of those objects must also be serialized with the bean, etc.

Therefore, it's very important for the bean designer to be careful about non-transient instance variables. In particular, variables that contain arbitrary lists or references to external objects (such as Vector and Hashtable variables that are filled with objects from outside the bean package) should be used with great caution; if there's a possibility that such a variable could contain a reference to a non-serializable object, then the variable must be marked transient.

This point cannot be over-stressed: the fact that a class implements Serializable does not guarantee that it will serialize correctly.

Taking all of this into consideration, it's generally a good idea to make bean instance variables transient whenever this is possible without loss of important information. In addition to making bean verification easier, transient variables don't contribute to the size of the output produced by serialization.

Transience is good!

Deserialization

The values of transient instance variables are not saved when a bean is serialized. This creates a problem when a saved bean is later deserialized: these variables may need to be initialized in order for the bean to be usable. This is accomplished by providing a special readObject method that is called by the JVM whenever the bean is read from a stream. The following is the most basic readObject method that should be used:

    private void readObject(java.io.ObjectInputStream in) 
    throws IOException, ClassNotFoundException {
        in.defaultReadObject();
    }

Calling in.defaultReadObject() will restore all non-transient variables to their values when the object was serialized, leaving the transient variables set to null. Thus, transient variables should be initialized to their default values after defaultReadObject has returned. The MyLine example bean does this by calling its initialize method, in which it constructs a transient Vector and sets up a MouseListener to handle mouse clicks (since all AWT event-listener registration is transient). This same initialize method is also called by the constructor of the class, effectively localizing the initialization of transient state.

Here are a few important things to note about the readObject method:

  1. The readObject method must be private! Otherwise, it will be ignored.
  2. There is no need to call super.readObject (you can't!). This is performed automatically as the object is being deserialized.

Externalization

A lower-level alternative to implementing the Serializable interface is to implement java.io.Externalizable interface. This alternative allows the bean developer to take complete control over the serialization process, allowing smaller output size and custom file formats.

To implement the Externalizable interface, a class must provide two methods:

For more information about this alternative serialization method, see the API documentation for Externalizable.