CONTENTS | PREV | NEXT Java Object Serialization Specification


4.4 Stream Unique Identifiers

Each versioned class must identify the original class version for which it is capable of writing streams and from which it can read. For example, a versioned class must declare:

    private static final long serialVersionUID = 3487495895819393L;
The stream-unique identifier is a 64-bit hash of the class name, interface class names, methods, and fields. The value must be declared in all versions of a class except the first. It may be declared in the original class but is not required. The value is fixed for all compatible classes. If the SUID is not declared for a class, the value defaults to the hash for that class. Serializable classes do not need to anticipate versioning; however, Externalizable classes do. The initial version of an Externalizable class must output a stream data format that is extensible in the future. The initial version of the method readExternal has to be able to read the output format of all future versions of the method writeExternal.

The serialVersionUID is computed using the signature of a stream of bytes that reflect the class definition. The National Institute of Standards and Technology (NIST) Secure Hash Algorithm (SHA-1) is used to compute a signature for the stream. The first 8 bytes of the signature are used to form a 64-bit hash. A java.lang.DataOutputStream is used to convert primitive data types to a sequence of bytes. The values input to the stream are defined by the JavaTM Virtual Machine (VM) specification for classes.

The sequence of items in the stream is as follows:

  1. Class name, written using UTF encoding.
  2. Class modifiers, written as a 32-bit integer.
  3. The name of each interface, sorted by name and written using UTF encoding.
  4. For each field of the class sorted by field name (except private static and private transient fields):
    1. Field name, in UTF encoding.
    2. Field modifiers, written as a 32-bit integer.
    3. Field descriptor, in UTF encoding.
  5. If a class initializer exists, write out the following:
    1. Method name, <clinit>, in UTF encoding.
    2. Method modifier, java.lang.reflect.Modifier.STATIC, written as a 32-bit integer.
    3. Method descriptor, ()V, in UTF encoding.
  6. For each non-private constructor sorted by method name and signature:
    1. Method name, <init>, in UTF encoding.
    2. Method modifiers, written as a 32-bit integer.
    3. Method descriptor, in UTF encoding.
  7. For each non-private method sorted by method name and signature:
    1. Method name, in UTF encoding.
    2. Method modifiers, written as a 32-bit integer.
    3. Method descriptor, in UTF encoding.
  8. The SHA-1 algorithm is executed on the stream of bytes produced by DataOutputStream and produces 20 byte values sha[0..19].
  9. The hash value is assembled from the first 8 byte values of the sha array.
    long h = 0;
    for (int i = 0; i < Math.min(8, sha.length); i++) {
        h += (long) (sha[i] & 255) << (i * 8);
    }


CONTENTS | PREV | NEXT
Copyright © 1997-1998 Sun Microsystems, Inc. All Rights Reserved.