Serializable
.
The object stream classes are
ObjectInputStream
and
ObjectOutputStream
. These classes implement
ObjectInput
and
ObjectOutput
,
which are subinterfaces of DataInput
and
DataOutput
. That means that all the primitive data I/O
methods covered in Data Streams are also
implemented in object streams. So an object stream can contain a
mixture of primitive and object values.
The
ObjectStreams
example illustrates this. ObjectStreams
creates the
same application as DataStreams
, with a couple of
changes. First, prices are now
BigDecimal
objects, to better represent fractional values. Second, a
Calendar
object is written to the data file, indicating an invoice date.
If readObject()
doesn't return the object type expected,
attempting to cast it to the correct type may throw a
ClassNotFoundException
.
In this simple example, that can't happen, so we don't try to catch
the exception. Instead, we notify the compiler that we're aware of the
issue by adding ClassNotFoundException
to the
main
method's throws
clause.
writeObject
and readObject
methods are
simple to use, but they contain some very sophisticated object
management logic. This isn't important for a class like Calendar,
which just encapsulates primitive values. But many objects contain
references to other objects. If readObject
is to
reconstitute an object from a stream, it has to be able to
reconstitute all of the objects the original object referred to. These
additional objects might have their own references, and so on. In this
situation, writeObject
traverses the entire web of object
references and writes all objects in that web onto the stream. Thus a
single invocation of writeObject
can cause a large number
of objects to be written to the stream.
This is demonstrated in the following figure, where
writeObject
is invoked to write a single object named
a. This object contains references to objects
b and c, while b contains references to d
and e. Invoking writeobject(a)
writes not just
a, but all the objects necessary to reconstitute a, so
the other four objects in this web are written also. When a
is read back by readObject
, the other four objects are
read back as well, and all the original object references are
preserved.
I/O of multiple referred-to objects
ob
twice
to a stream:
Object ob = new Object(); out.writeObject(ob); out.writeObject(ob);
writeObject
has to be matched by a
readObject
, so the code that reads the stream back will
look something like this:
Object ob1 = in.readObject(); Object ob2 = in.readObject();
ob1
and ob2
,
that are references to a single object.
However, if a single object is written to two different streams, it is effectively duplicated — a single program reading both streams back will see two distinct objects.