Whether you use a custom SUID or let serialver calculate one for you, you are responsible for deciding when a change to a class is compatible with serialization. The serialver tool does not necessarily generate the same SUID for two compatible but different classes. Only the programmer can decide whether a new SUID is required.p. 286: The last sentence before Example 11-3 should be changed from "Invocations of the normal
ZipFile
methods, like entries()
or
getInputStream()
methods, are merely passed along to the zf
field
java.io
." to "Invocations of the normal ZipFile
methods, like entries()
or
getInputStream()
, are merely passed along to the ZipFile
field
zf
."
p. 288: In the second paragraph, change
"the virtual machine creates a new
ZipFile
object out of thin air"
to
"the virtual machine creates a new
SerializableZipFile
object out of thin air".
p. 288: In the last paragraph change
SerializableRandomAccessFile
to SerializableZipFile
.
p. 289: The second sentence of the first paragraph should read
"In this case, you can use ObjectOutputStream
's
defaultWriteObject()
method to write the state
of the object, then use ObjectInputStream
's
defaultReadObject()
method to read the state of the object."
That is, change the second ObjectOutputStream
to
ObjectInputStream
.
p. 291:
In the first paragraph in the Preventing Serialization
section, a space is missing after "by
throwing a NotSerializableException
from writeObject()
." In other words, the last two sentences should
read
You can prevent an object from being serialized, even though it or one of its superclasses implementsp. 291: At the bottom of the page,Serializable
, by throwing aNotSerializableException
fromwriteObject()
.NotSerializableException
is a subclass ofjava.io.ObjectStreamException
which is itself a kind ofIOException
:
throws new NotSerializableException()
should be
throw new NotSerializableException()
(both times). That is, it
should read:
private void writeObject(ObjectOutputStream out) throws IOException {
throw new NotSerializableException();
}
private void readObject(ObjectInputStream in) throws IOException {
throw new NotSerializableException();
}
p. 298: In the last paragraph change "linked list" to "hashtable"
p. 299: Example 11-6, the Person
class is pretty solidly broken, and doesn't
really do what it claims to do. Here's a much improved version
with lots of fixes, and that also includes a main() method for testing:
import java.util.*;
import java.io.*;
public class Person implements Serializable, ObjectInputValidation {
static Hashtable thePeople = new Hashtable();
String name;
String ss;
public Person(String name, String ss) {
this.name = name;
this.ss = ss;
thePeople.put(ss, name);
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.registerValidation(this, 5);
in.defaultReadObject();
}
public void validateObject() throws InvalidObjectException {
if (thePeople.containsKey(this.ss)) {
throw new InvalidObjectException(this.name + " already exists");
}
else {
thePeople.put(this.ss, this.name);
}
}
public String toString() {
return this.name + "\t" + this.ss;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person p1 = new Person("Rusty", "123-45-5678");
Person p2 = new Person("Beth", "321-45-5678");
Person p3 = new Person("David", "453-45-5678");
Person p4 = new Person("David", "453-45-5678");
Enumeration en = thePeople.elements();
while (en.hasMoreElements()) {
System.out.println(en.nextElement());
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(bout);
oout.writeObject(p1);
oout.writeObject(p2);
oout.writeObject(p3);
oout.writeObject(p4);
oout.flush();
oout.close();
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream oin = new ObjectInputStream(bin);
try {
System.out.println(oin.readObject());
System.out.println(oin.readObject());
System.out.println(oin.readObject());
System.out.println(oin.readObject());
}
catch (InvalidObjectException e) {
System.err.println(e);
}
oin.close();
// now empty the hashtable and try again
thePeople.clear();
bin = new ByteArrayInputStream(bout.toByteArray());
oin = new ObjectInputStream(bin);
try {
System.out.println(oin.readObject());
System.out.println(oin.readObject());
System.out.println(oin.readObject());
System.out.println(oin.readObject());
}
catch (InvalidObjectException e) {
System.err.println(e);
}
oin.close();
en = thePeople.elements();
while (en.hasMoreElements()) {
System.out.println(en.nextElement());
}
}
}