Suppose we have an arbitrary graph represented by nodes and pointers like this:
class Node
{
public ValueType data;
public ArrayList<Node> adj;
}
Now, I want to take a copy of it or write/read it on the disk (AKA serialize/deserialize). I also know that it can be done using a search algorithm + associative arrays. And, it turns out that this method is called swizzling.
Here goes my question:
I have heard that in Java by declaring the class as Serializable, this feature is provided for you automatically. (which sounds like a magic to me!)
Is this statement correct? Does Java automatically run BFS to traverse the graph and swizzle the pointers? In other words, does serialize/deserialize clone the object for me? (a completely brand new object with the same structure but new nodes and updated pointers)
If yes, then what if in some cases I just want to copy the pointers? what if I want to serialize the object just to keep the original pointers?
I appreciate any comments on this. :-)
I'll address your last question first. The purpose of serialization is not cloning an object graph in memory. It is to transform an object graph to a stream of bytes in order to do things like saving in a file or sending across the wire. The deserialization process might be done on a different computer, at a different time, in a different process, or even by a non-Java program, so it is not a reasonable expectation to get references to the same objects as before. It is the structure and contents of the object graph that are being saved and later restored, not in-memory addresses. For precisely this reason, it does not make sense for all objects to be serializable. For instance, serializing a
Thread
is not going to be useful, because it is not going to be meaningful outside the current instance of a program.The magic behind automatic serialization is not very complex. Ignoring custom serialization methods that you can write for your own classes to precisely control the serialization and deserialization behavior, yes, the system will effectively traverse the object graph in order to generate a stream of bytes. This traversal is generally done as a DFS, not BFS. Basically, you ask Java to serialize an object, passing a reference to it. That reference will serve as the root of the object graph. From there, Java will recursively serialize the fields of that object. Of course, it does track circular references and writes out appropriate markings in the output stream so that the deserializer is able to hook up the pointers and recreate the structure as it was before.