It's said that Java's default serialization mechanism is not very efficient because a)it discovers which fields to write/read through reflection which is usually slow b) it writes extra data to stream.
One way to make it more efficient is to implement Externalizable and its writeExternal/readExternal methods.
Here's the question: if I instead provide 'writeObject/readObject' methods and don't call deafiltWriteObject/defaultReadObject in them, then this mechanism won't use reflection to figure out which fields to write/read, plus it won't write extra data to stream (or will it? not sure). So from an efficiency perspective, is implementing writeObject/readObject mentioned above same as implementing Externalizable? Or does the latter option give some more practical benefits which the former doesn't?
EDIT: a difference, ofcourse, is when a Serializable class implementing readObject/writeObject is subclassed, and if the subclass has its own readObject/writeObject, they don't need to call super's readObject/writeObject. Not so if the super/subclass instead implement Externalizable. In this case, super's writeExternal/readExternal need to be explicitly called. However, this difference is irrelevant from an efficiency point of view.
There is still some over head in choosing which class/writeObject/readObject to call next. but it is significantly reduced.
This can perform the same as Externalizable depending on what you are doing and whether you use the extra options it gives you. e.g. readObject assumes you to create a new object each time, Externalizable has readResolve which means you can reuse objects.
http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/input.html
In many cases, recycling objects is the "next" step in speeding up deserialization. (Assuming that's an option for you)
http://vanillajava.blogspot.co.uk/2011/10/recycling-objects-to-improve.html
Found a couple of things while experimenting and going through serialization mechanism's code:
1) if the object is found to be Externalizable, it's cast to Externalizable, and corresponding method is called on it; whereas for Serializable object, it's reflectively checked if it has readObject/writeObject. So maybe this makes it slightly slower,
2) the amount of data written for Externalizable is a little less than Serializable with readObject/writeObject (I found a difference of 1 byte for the following code when I wrote object of B).
For Externalizable:
static class A implements Externalizable
{
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
System.out.println("A write called");
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
System.out.println("A read called");
}
}
static class B extends A implements Externalizable
{
@Override
public void writeExternal(ObjectOutput out) throws IOException
{
super.writeExternal(out);
System.out.println("B write called");
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
{
super.readExternal(in);
System.out.println("B read called");
}
}
For Serializable:
static class A implements Serializable
{
private void writeObject(ObjectOutputStream out) throws IOException
{
System.out.println("A write called");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
System.out.println("A read called");
}
}
static class B extends A implements Serializable
{
private void writeObject(ObjectOutputStream out) throws IOException
{
System.out.println("B write called");
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
{
System.out.println("B read called");
}
}
The major difference, in terms of class design, is that Serializable
will work on any class, whereas Externalizable
only works on mutable classes with public default (no-arg) constructors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With