Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 4 of 6
Those private methods can be used for any customization you need to make to the serialization process. Encryption could be added to the output and decryption to the input (note that the bytes are written and read in cleartext with no obfuscation at all). They could be used to add extra data to the stream, perhaps a company versioning code. The possibilities are truly limitless.
OK, we have seen quite a bit about the serialization process, now let's see some more. What if you create a class whose superclass
is serializable but you do not want that new class to be serializable? You cannot unimplement an interface, so if your superclass
does implement Serializable, your new class implements it, too (assuming both rules listed above are met). To stop the automatic serialization, you can
once again use the private methods to just throw the NotSerializableException. Here is how that would be done:
10 private void writeObject(ObjectOutputStream out) throws IOException
20 {
30 throw new NotSerializableException("Not today!");
40 }
50 private void readObject(ObjectInputStream in) throws IOException
60 {
70 throw new NotSerializableException("Not today!");
80 }
Any attempt to write or read that object will now always result in the exception being thrown. Remember, since those methods
are declared private, nobody could modify your code without the source code available to them -- no overriding of those methods would be allowed
by Java.
Our discussion would be incomplete not to mention the third option for serialization: create your own protocol with the Externalizable interface. Instead of implementing the Serializable interface, you can implement Externalizable, which contains two methods:
public void writeExternal(ObjectOutput out) throws IOException;public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;Just override those methods to provide your own protocol. Unlike the previous two serialization variations, nothing is provided
for free here, though. That is, the protocol is entirely in your hands. Although it's the more difficult scenario, it's also
the most controllable. An example situation for that alternate type of serialization: read and write PDF files with a Java
application. If you know how to write and read PDF (the sequence of bytes required), you could provide the PDF-specific protocol
in the writeExternal and readExternal methods.
Just as before, though, there is no difference in how a class that implements Externalizable is used. Just call writeObject() or readObject and, voila, those externalizable methods will be called automatically.
There are a few things about the serialization protocol that can seem very strange to developers who are not aware. Of course, that is the purpose of the article -- to get you aware! So let's discuss a few of those gotchas and see if we can understand why they exist and how to handle them.
First, consider the situation in which an object is written to a stream and then written again later. By default, an ObjectOutputStream will maintain a reference to an object written to it. That means that if the state of the written object is written and then
written again, the new state will not be saved! Here is a code snippet that shows that problem in action: