Friday, April 24, 2009

Serializing non-serializable objects using readObject and writeObject

Basic serialization is pretty straightforward, just make the class implement the Serializable interface. Serializable is a marker interface, so pretty much it involves nothing i.e. implementing no methods. Also if one of the super classes of the class is serializable then the class is automatically serializable. Here the basic assumption is that all the member variables of the class are serializable. However that isn't always the case. Class sometimes contains one or more member variables that are not serializable. In such cases, one of the mechanisms to make the class serializable is to do the following:
- Mark the non-serializable fields transient. So these are not saved as part of the object state.
- Implement the following methods in the class:
private void writeObject(ObjectOutputStream out) throws IOException;
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

When the above methods are implemented first call the defaultReadObject/defaultWriteObject to save the state of the serializable member fields and then proceed to read/write the transient variables. Here is an example:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class MySerializationTest implements Serializable{

private static final long serialVersionUID = 1L;
transient Color color;
int length;

public MySerializationTest(String color, int length) {
this.color = new Color(color);
this.length = length;
}

//Deserialization
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
color = new Color((String)ois.readObject());
}

//Serialization
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(color.getColor());
}

@Override
public String toString() {
StringBuffer str = new StringBuffer();
str.append("Color:" + color.getColor());
str.append(" length:" + length);
return str.toString();
}

public static void main(String[] args) throws IOException, ClassNotFoundException {
String filename = "Ser.ser";
MySerializationTest mySer = new MySerializationTest("Green", 20), mySer2;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
oos = new ObjectOutputStream(new FileOutputStream(filename));
//Write serialized object to file
oos.writeObject(mySer);
ois = new ObjectInputStream(new FileInputStream(filename));
//read the serialized object
mySer2 = (MySerializationTest)ois.readObject();
System.out.println(mySer2);
} finally {
oos.close();
ois.close();
}


}

}

//Non serialized class
class Color {

private String color;

public Color(String color) {
this.color = color;
}

public void setColor(String color) {
this.color = color;
}

public String getColor() {
return color;
}

}


Output:
Color:Green length:20

No comments:

Post a Comment