How to customize serialization of an
object?
Serialization
of a class can be customized by making that class implement interface
Externalizable. This interface requires two methods to be implemented
:
void
writeExternal(ObjectOutput
out) throws
IOException
void
readExternal(ObjectInput
in) throws
IOException,
ClassNotFoundException
The
order of reading in readExternal should be same as that of writing in
writeExternal else custom serialization will fail. Example:
public class TestCustomSerial implements Externalizable {
private int i = 5;
private String s = "abc";
public void writeExternal(ObjectOutput out) throws IOException
{
out.writeObject(s);
out.writeInt(i);
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
s = (String) in.readObject();
i = in.readInt();
}
}
Serialization
can be used to implement deep-cloning (though very inefficient) but
it will ensure quick and error-free deep-cloning (provided all its
members are primitive or serializable). Example:
class SerialCloneable implements Cloneable, Serializable
{
public Object clone()
{
try
{
// save the object to a byte array
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
out.writeObject(this);
out.close();
// read a clone of the object from the byte array
ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
ObjectInputStream in = new ObjectInputStream(bin);
Object ret = in.readObject();
in.close();
return ret;
}
catch (Exception e)
{
return null;
}
}
}
Now,
any class whose quick and accurate deep-clone is desired, can extend
this class.
When
we will call clone on that class, it will call the above method and
provide an exact clone of the original object.
Members
of a class are not serialized if:
Member
is non-primitive and does not implement serializable.
Member
is static since static members are not related to any object.
Member
is declared transient.
Member
is inherited from base-class and base-class is non-serializable.
Java
serializer handles cyclic objects and does not write the object again
if it has been serialized once as part of the current serialization
cycle. It however puts a reference in the serialized form so that
when we de-serialize it, the cyclic order between objects is
restored.
|