THE Java™ Programming Language, Fourth Edition

(Jeff_L) #1

were serialized.


public class BetterName implements Serializable {
private String name;
private long id;
private transient int hash;
private static long nextID = 0;


public BetterName(String name) {
this.name = name;
synchronized (BetterName.class) {
id = nextID++;
}
hash = name.hashCode();
}


private void writeObject(ObjectOutputStream out)
throws IOException
{
out.writeUTF(name);
out.writeLong(id);
}


private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
name = in.readUTF();
id = in.readLong();
hash = name.hashCode();
}


public int hashCode() {
return hash;
}


// ... override equals, provide other useful methods
}


We use writeObject to write out each of the non-static, non-transient fields. It declares that it can throw
IOException because the write methods it invokes can do so, and, if one does throw an exception, the
serialization must be halted. When readObject gets the values from the stream, it can then set hash
properly. It, too, must declare that it throws IOException because the read methods it invokes can do so,
and this should stop deserialization. The readObject method must declare that it throws
ClassNotFoundException because, in the general case, deserializing fields of the current object could
require other classes to be loadedthough not in the example.


There is one restriction on customized serialization: You cannot directly set a final field within
readObject because final fields can only be set in initializers or constructors. For example, if name was
declared final the class BetterName would not compile. You will need to design your classes with this
restriction in mind when considering custom serialization. The default serialization mechanism can bypass
this restriction because it uses native code. This means that default serialization works fine with classes that
have final fields. For custom serialization it is possible to use reflection to set a final fieldsee "Final Fields"
on page 420but the security restrictions for doing this means that it is seldom applicable. One circumstance in
which it is applicable, for example, is if your classes are required to be installed as a standard extension and so
have the necessary security privilegessee "Security Policies" on page 680.


The readObject and writeObject methods for BetterName show that you can use the methods of
DataInput and DataOutput to transmit arbitrary data on the stream. However, the actual
implementations replicate the default serialization and then add the necessary setup for hash. The read and

Free download pdf