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.

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

the resolveClass() method would need to have a class loader that read the data from the<br />

stream. If annotateClass() wrote the URL of the class to the stream, then the<br />

resolveClass() method would need a class loader that read the URL from the stream and<br />

downloaded the class from that URL.<br />

The resolveClass() method is called exactly once for each class encountered in the stream<br />

(not just those written by annotateClass()). resolveClass() is responsible for knowing<br />

what sort of data needs to be read to reconstruct the class and for reading it from the input<br />

stream. resolveClass() should then load and return the class. If it can't do so, it should<br />

throw a ClassNotFoundException . If it returns a class, but that class's SUID does not match<br />

the SUID of the class in the stream, then the runtime throws a ClassNotFoundException.<br />

11.10 Resolving Objects<br />

There may be occasions where you want to replace the objects read from the stream with<br />

other, alternative objects. Perhaps an old version of a program whose data you need to read<br />

used Franc objects, but the new version of the program uses Euro objects. The<br />

ObjectInputStream can replace each Franc object read with the equivalent Euro object.<br />

Only trusted subclasses of ObjectInputStream may replace objects. A class is only trusted if<br />

it was loaded from the local class path; that is, the class loader returned by<br />

getClassLoader() is null. To make it possible for a trusted subclass to replace objects, you<br />

must first pass true to its enableResolveObject() method:<br />

protected final boolean enableResolveObject(boolean enable)<br />

throws SecurityException<br />

Generally, you would do this in the constructor of any class that needed to replace objects.<br />

Once object replacement is enabled, whenever an object is read, it is passed to the<br />

ObjectInputStream subclass's resolveObject() method before readObject() returns:<br />

protected Object resolveObject(Object o) throws <strong>IO</strong>Exception<br />

The resolveObject() method may return the object itself (the default behavior) or return<br />

a different object. Resolving objects is a tricky business. The substituted object must be<br />

compatible with the use of the original object, or errors will soon surface as the program tries<br />

to invoke methods or access fields that don't exist. Most of the time, the replacing object is an<br />

instance of a subclass of the class of the replaced object. Another possibility is that the<br />

replacing object and the object it replaces are both instances of different subclasses of<br />

a common superclass or interface, where the original object was only used as an instance of<br />

that superclass or interface.<br />

11.11 Validation<br />

It is not always enough to merely restore the state of a serialized object. You may need to<br />

verify that the value of a field still makes sense, you may need to notify another object that<br />

this object has come into existence, or you simply may need to have the entire graph of<br />

the object available before you can finish initializing it.<br />

261

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

Saved successfully!

Ooh no, something went wrong!