Page 2 of 6
suid.
suid in the current version of the serializable class with the value saved in the object serialized with the class's prior version.
This approach provides Java serialization its version control mechanism.
java.io.InvalidClassException: MySerializableClass; Local class not compatible: stream classdesc serialVersionUID=7187368850772554122 local class serialVersionUID=4104486680721271886
at java.io.ObjectStreamClass.validateLocalClass(ObjectStreamClass.java:565)
at java.io.ObjectStreamClass.setClass(ObjectStreamClass.java:609)
at java.io.ObjectInputStream.inputClassDescriptor(ObjectInputStream.java:981)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:402)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:272)
at java.io.ObjectInputStream.inputObject(ObjectInputStream.java:1231)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:272)
at MyDeserializeClient.main(MyDeserializeClient.java:27)
The suid is set in one of two ways, with the first being the default mechanism described above. The Java serialization mechanism automatically
computes a hash value. ObjectStreamClass's computeSerialVersionUID method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns
a hash value. This computation technique ensures that most changes in an object's "shape" and attribute types result in different
hash values. I elaborate on the significance of this default suid generation later when I discuss release compatibility.
In the second approach, the developer explicitly sets suid in the serializable class, as shown in the code below:
package java.io;
public class MySerializableClass implements Serializable {
private static final long serialVersionUID = 1999L;
static String notSerializableString = "static field not serialized";
transient Thread T1; /* Transient field not serialized */
public int aNum = 0;
public String serializedString = "a serialized string";
private void writeObject (ObjectOutputStream s)
throws IOException {
s.defaultWriteObject ();
// Followed by customized serialization code
}
private void readObject (ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject ();
// Followed by customized deserialization code
}
}
A developer can set the suid with any integer value. However, a developer can also pass the class name to a Java command—serialver—which computes a hash value using the same algorithm described above. The developer then pastes the return value into the
source code. In the following sections, I discuss why it is important for the developer of a serializable class to explicitly
set the suid in the code.
Changes to a serializable class can be either compatible or incompatible. A compatible change results in the evolved class being able to deserialize objects serialized by the class of a prior release. Conversely, the object serialized by the evolved class can be deserialized by the class's prior version. Compatible changes typically result from adding fields or objects to the object graph. With the addition of fields or objects, the default Java serialization read-mechanism simply provides default values for the corresponding attribute types. Examples of compatible changes are the following:
Archived Discussions (Read only)