Java Reference
In-Depth Information
way to prevent this problem is to explicitly declare a version number for your
class. You do this by giving the class a constant field named
serialVersionUID
.
The value of this field doesn't matter; it must simply be the same for all versions of
the class that have a compatible serialization format. Since the original
IntList
class shown in Example 9-2 doesn't have a
serialVersionUID
field, its version
number was implicitly computed based on the API of the class. In order to give
the new version of
IntList
a version number that matches the original version,
use the
serialver
command that comes with the Java SDK:
% serialver com.davidflanagan.examples.serialization.IntList
IntList:
static final long serialVersionUID = 4538804519406678841L;
Now run
serialver
and specify the name of the original version of the class.
seri-
alver
prints a field definition suitable for inclusion in the modified version of the
class. By including this constant field in the modified class, you retain serialization
compatibility between it and the original version.
Advanced Versioning
Sometimes you make changes to a class that alters the way the class stores its
state. Imagine a
Rectangle
class that represents the rectangle as the coordinate of
the upper-left corner, plus a width and a height. Now suppose that the class is
reimplemented so that it maintains exactly the same public API, but the rectangle
is now represented by two points: the coordinates of the upper-left corner and the
lower-right corner. The internal private fields of the class have changed, so it
would appear that serialization compatibility between the two implementations of
the class is simply not possible.
In Java 1.2 and later, however, the serialization mechanism has been updated to
allow the serialization format to be totally decoupled from the fields used by a
particular implementation or version of the class. A class can now declare a private
field named
serialPersistentFields
that refers to an array of
java.io.Object-
StreamField
objects. Each of these objects defines a field name and a field type.
These fields need not have any relationship to the fields implemented by the class;
they are the fields of the serialized form of the class. By defining this array of
ObjectStreamField
objects, the class is specifying its serialization format. When a
new version of the class is defined, that new version must be able to save and
restore its state in the format defined by the
serialPersistentFields
array.
The techniques for reading and writing the serialization fields declared by the
serialPersistentFields
array are beyond the scope of this chapter. For more
information, check the
putFields()
and
writeFields()
methods of
ObjectOut-
putStream
and the
readFields()
method of
ObjectInputStream
. See also the
advanced serialization examples supplied as part of the Java SDK documentation.
Serialized Applets
One particularly interesting application of object serialization is serialized applets
(see Chapter 15,
Applets
). As of Java 1.1, the HTML
<APPLET>
tag has a new
attribute,
OBJECT
, that can be used in place of the
CODE
attribute to specify a