When creating an object that can be serialized, one design consideration is whether all the object’s instance variables should be saved. In some cases, an instance variable must be created from scratch each time the object is restored. A good example is an object referring to a file or input stream. Such an object must be created anew when it is part of a serialized object loaded from an object stream, so it doesn’t make sense to save this information when serializing the object. It’s a good idea to exclude from serialization a variable that contains sensitive information. If an object stores the password needed to gain access to a resource, that password is more at risk if serialized into a file. The password also might be detected if it is part of an object restored over a stream that exists on a network. A third reason not to serialize a variable is to save space on the storage file that holds the object. If its values can be established without serialization, you might want to omit the variable from the process.
To prevent an instance variable from being included in serialization, the transient modifier is used. This modifier is included in the statement that creates the variable, preceding the class or data type of the variable. The following statement creates a transient variable called limit:
public transient int limit = 55;
Checking an Object’s Serialized Fields
An important thing to consider when serializing objects is how easily a malicious programmer could tamper with an object in serial form. The file format for serialized objects in Java is neither encrypted nor particularly complex. When you create an object again from its serial form, you can’t rely on a constructor method to ensure that its fields have permissible values. Instead, to check that an object read from a stream contains acceptable values, the object can include a readObject(ObjectInputStream) method. This method throws IOException and ClassNotFoundException exceptions and takes the following form:
private void readObject(ObjectInputStream ois) {
ois.defaultReadObject();
}
Note that it is private. In the method, the defaultReadObject() method of the object stream reads serialized fields into the object, where they can be checked to ensure that the values are acceptable. If not, an IOException can be thrown to indicate that an error has occurred related to serialization.The following method could be added to the Message class to reject a serialized object that has an empty from value:
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
if (from.length() < 1) {
throw new IOException(“Null sender in message.”);
}
}