Documenting the serialized form of a class is important when you need to interoperate with different implementations of the same API. For instance, the open source GNU Classpath library should be able to deserialize objects serialized by Sun's class library and vice versa, even though they share no code and indeed may have quite different private data. JavaDoc has three tags specifically to document the serialized form of a class: @serial, @serialField, and @serialData. The javadoc application reads these tags to generate a description of the serialization format of each Serializable class.
13.12.1. @serial
An @serial tag should be attached to each nontransient instance field. The content of this tag should describe the meaning of the field and the any constraints on its values. For example, this is how you might document the x and y fields in the TwoDPoint class:
import java.io.Serializable; public class TwoDPoint implements Serializable { /** @serial the X-coordinate of the point; * any double value except NaN */ private double x; /** @serial the Y-coordinate of the point; * any double value except NaN */ private double y; //...
This is a major violation of data encapsulation, but then serialization pretty much always is. Of course, there's no rule that says an alternate implementation of this class has to use two double x and y fields. It could use BigDecimals or doubles expressing polar coordinates. However, for compatibility when serializing, it should be prepared to write two doubles expressing Cartesian coordinates. The serialized form ultimately becomes just another part of the class's published interface, albeit one you can ignore for most operations.
13.12.2. @serialData
A class that customizes the serialization format by implementing writeObject( ) or writeExternal( ) should annotate those methods with an @serialData tag explaining in detail the format written. For example, the writeObject( ) method in SerializableZipFile could be documented like this:
/** @serialData the name of the file is written as a String. * No other data is written. */ private void writeObject(ObjectOutputStream out) throws IOException { out.writeObject(zf.getName( )); }
This example's quite simple. Of course, the more complex the custom serialization format, the longer and more complex the comment will be.
13.12.3. @serialField
Finally, if you have a serialPersistentFields array, each ObjectStreamField component of the array should be documented by @serialField tag. This tag is followed by the name of the field, the type of the field, and the description of the field. For example, this comment documents a serialPersistentFields array for the TwoDPoint:
/** * @serialField x double the Cartesian x-coordinate; never NaN * @serialField y double the Cartesian y-coordinate; never NaN */ private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("x", double.class), new ObjectStreamField("y", double.class) };
|
Basic I/O
Introducing I/O
Output Streams
Input Streams
Data Sources
File Streams
Network Streams
Filter Streams
Filter Streams
Print Streams
Data Streams
Streams in Memory
Compressing Streams
JAR Archives
Cryptographic Streams
Object Serialization
New I/O
Buffers
Channels
Nonblocking I/O
The File System
Working with Files
File Dialogs and Choosers
Text
Character Sets and Unicode
Readers and Writers
Formatted I/O with java.text
Devices
The Java Communications API
USB
The J2ME Generic Connection Framework
Bluetooth
Character Sets