23.07.2013 Views

Java IO.pdf - Nguyen Dang Binh

Java IO.pdf - Nguyen Dang Binh

Java IO.pdf - Nguyen Dang Binh

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Java</strong> I/O<br />

Needless to say, this is a lot of work. You would have to define readState() and<br />

writeState() methods for every class whose instances you wanted to serialize. Furthermore,<br />

you would have to track where in the byte stream particular values were stored, to make sure<br />

that you didn't accidentally read the y coordinate of one point as the x coordinate of the next.<br />

You'd also have to make sure you could serialize the object's superclasses, if the superclass<br />

contained a relevant state. Classes composed of other classes would cause a lot of trouble,<br />

since you'd need to serialize each object the first object contained, then each object those<br />

objects contained, then the objects those objects contained, and so forth. Finally, you'd need to<br />

avoid circular references that could put you in an infinite loop.<br />

Fortunately, Sun's done all the work for you. <strong>Java</strong> 1.1 and later virtual machines possess code<br />

that allows them to read the nonstatic, nontransient fields of an object and write them out in a<br />

well-specified format. All you have to do is chain object output streams to an underlying<br />

stream where you want the object to be written and call write(); you do not have to add any<br />

new methods. Reading objects in from an object input stream is only slightly more<br />

complicated; as well as reading the object from the stream, you also need to cast the object to<br />

the correct type.<br />

11.4 Performance<br />

Serialization is often the easiest way to save the state of your program. You simply write out<br />

the objects you're using, then read them back in when you're ready to restore the document.<br />

There is a downside, however. First of all, serialization is slow. If you can define a custom file<br />

format for your application's documents, using that format will almost certainly be much<br />

faster than object serialization.<br />

Second, serialization can slow or prevent garbage collection. Every time an object is written<br />

onto an object output stream, the stream holds on to a reference to the object. Then, if the<br />

same object is written onto the same stream again, it can be replaced with a reference to its<br />

first occurrence in the stream. However, this means that your program holds on to live<br />

references to the objects it has written until the stream is reset or closed—which means these<br />

objects won't be garbage-collected. The worst-case scenario is when you keep a stream open<br />

as long as your program runs and write every object you create onto the stream. This prevents<br />

any objects from being garbage-collected.<br />

The easy solution is to avoid keeping a running stream of the objects you create. Instead, save<br />

the entire state only when the entire state is available, and then close the stream immediately.<br />

If this isn't possible, you have the option to reset the stream by invoking its reset() method:<br />

public void reset() throws <strong>IO</strong>Exception<br />

reset() flushes the ObjectOutputStream object's internal cache of the objects it has already<br />

written so they can be garbage-collected. However, this also means that an object may be<br />

written onto the stream more than once, so use this method with caution.<br />

11.5 The Serializable Interface<br />

Unlimited serialization would introduce some security problems. For one thing, it allows<br />

unrestricted access to an object's private fields. By chaining an object output stream to a byte<br />

241

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!