Serialization is the process of writing an object to a file. Deserialization is the inverse process.
Serialization isn't as straight forward as it may seem. Consider writing the object a: A to a file:
Object a links to objects b and c which link to d and e, and e links back to a.
If we write a to a file, we must also write b, c, d, and e. We want to avoid getting into an infinite loop caused by the fact that e links back to a. We also want to avoid writing d to the file twice as it is linked by b and c.
Deserialization is also complicated. The links in the diagram are physical addresses. We could write them to a file, but when we read them back these addresses will be meaningless. Also, how will the deserializing program know how much memory to allocate for each object?
Solving this problem in languages like C++ programmers must solve all of these problems. But Java solves these problems automatically. The programmer only needs to declare that a class of objects that need to be serialized implements the Serializable interface:
class A implements java.io.Serializable { ... }
class B implements java.io.Serializable { ... }
class C implements java.io.Serializable { ... }
class D implements java.io.Serializable { ... }
class E implements java.io.Serializable { ... }
If a serializable object contains a field that shouldn't be serialized, then that field should be declared volatile:
volatile int hitCount = 0;
The obsolescence problem occurs when an instance of a class A is written to a file, but then read at a later time by a program using an updated version of class A. To solve this problem we can declare version numbers in classes. The deserialization machinery automatically checks these numbers.
private
static final long serialversionUID
= 129348938L;
class Model implements Serializable {...}
String fName;
Model model = new Model();
try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(fName));
os.writeObject(model);
os.close();
} catch (Exception err) {
}
try {
ObjectInputStream is = new ObjectInputStream(new FileInputStream(fName));
newModel = (Model)is.readObject();
is.close();
} catch (Exception
err) {
}
A stream is a sequence of bytes of indeterminant length.
An input stream connects a program to a data source such as a file, device, or another program.
An output stream connects a program to a data destination, which could also be a file, device, or another program.
The basic read method returns an array of bytes from a data source. We can enhance this using a variant of the Proxy Pattern called the Decorator Pattern. In this pattern proxies are called decorators.
Proxys/Decorators can be organized into pipelines:
For more on streams in Java see I/O Streams in Java.