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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

11.8.1 The readObject( ) and writeObject( ) Methods<br />

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

The code that serializes objects is built into the virtual machine and is not part of the<br />

ObjectInputStream and ObjectOutputStream classes. This allows the private data of an<br />

object to be read and written. If serialization was written in pure <strong>Java</strong> without any special<br />

access to the internals of all the different classes, it wouldn't be able to get at the private,<br />

internal state of most objects. However, as long as serialization is allowed to access private<br />

members of an object, that might as well be taken advantage of to customize the serialization<br />

process without affecting the picture of a class shown to the rest of the world.<br />

By default, serialization takes place as previously described. When an object is passed to an<br />

ObjectOutput's writeObject() method, the ObjectOutput reads the data in the object and<br />

writes it onto the underlying output stream in a specified format. Data is written starting with<br />

the highest serializable superclass of the object and continuing down through the hierarchy.<br />

However, before the data of each class is written, the virtual machine checks to see if the class<br />

in question has methods with these two signatures:<br />

private void writeObject(ObjectOutputStream out) throws <strong>IO</strong>Exception<br />

private void readObject(ObjectInputStream in)<br />

throws <strong>IO</strong>Exception, ClassNotFoundException<br />

(Actually, an ObjectOutput only checks to see if the object has a writeObject() method,<br />

and an ObjectInput only checks for a readObject() method, but it's rare to implement one<br />

of these methods without implementing the other.) If the appropriate method is present, it is<br />

used to serialize the fields of this class rather than writing them directly. The object stream<br />

still handles serialization for any superclass or subclass fields.<br />

For example, let's return to the issue of making a SerializableZipFile. Previously it wasn't<br />

possible, because the superclass, ZipFile, didn't have a no-argument constructor. In fact,<br />

because of this problem, no subclass of this class can be serializable. However, it is possible<br />

to use composition rather than inheritance to make our zip file serializable. [2] Example 11.3<br />

shows a SerializableZipFile class that does not extend java.util.zip.ZipFile.<br />

Instead, it stores a ZipFile object in a transient field in the class called zf. The zf field is<br />

initialized either in the constructor or in the readObject() method. Invocations of the normal<br />

ZipFile methods, like entries() or getInputStream(), are merely passed along to the<br />

ZipFile field zf.<br />

Example 11.3. SerializableZipFile<br />

import java.io.*;<br />

import java.util.*;<br />

import java.util.zip.*;<br />

public class SerializableZipFile implements Serializable {<br />

ZipFile zf;<br />

public SerializableZipFile(String filename) throws <strong>IO</strong>Exception {<br />

this.zf = new ZipFile(filename);<br />

}<br />

2 Design pattern aficionados may recognize what's about to happen as an application of the Decorator pattern so common in the java.io<br />

package. For more details, see Design Patterns, Erich Gamma, et al., pp. 179-184, Addison-Wesley, 1995.<br />

252

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

Saved successfully!

Ooh no, something went wrong!