4

I am not able to understand the basics of Serialization in Java 1.6.

Below is the Dog Class containing an instance variable of Collar Class:

Dog.java

public class Dog implements Serializable {

private Collar collar;

public Collar getCollar() {
    return collar;
}

public void setCollar(Collar collar) {
    this.collar = collar;
}

}

The Collar class does not implements Serializable interface as shown below:

Collar.java

public class Collar {

private int size;

public int getSize() {
    return size;
}

public void setSize(int size) {
    this.size = size;
}

}

Now when I try to serialize the Dog then why it does not throw an NotSerializableException ? According to the contract the entire object graph should implement Serializable but my Collar class does not fulfill that.

Below is the main method for this demo:

public static void main(String[] args) {
    try {
        FileOutputStream fs = new FileOutputStream("E:\\test.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        Dog dog = new Dog();
        // No exception thrown here, WHY?
        // test.ser file is getting created properly.
        os.writeObject(dog);

        FileInputStream fis = new FileInputStream("E:\\test.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Dog dog1 = (Dog)ois.readObject();
        // Here I am getting a null Collar object
        Collar c1 = dog1.getCollar();

Kindly explain this, I am totally confused while trying to implement all the theoretical stuffs :(

Jeremy Johnson
  • 469
  • 1
  • 4
  • 17
WhoAmI
  • 819
  • 4
  • 18
  • 35
  • 1
    Please add these lines `outputStream.flush();` `outputStream.close();` before you read from the file and then report back your findings – Multithreader Aug 18 '13 at 13:56
  • You said it yourself: the entire *object graph* must be serializable, not all the classes your code happens to mention. – Marko Topolnik Aug 18 '13 at 13:58
  • @Multithreader NO difference found if I add the two lines mentioned above – WhoAmI Aug 18 '13 at 14:38
  • @MarkoTopolnik Can you please elaborate your answer? It sounds interesting – WhoAmI Aug 18 '13 at 14:39
  • 1
    Well, your entire object graph is just the `Dog` object itself. It holds no references to any other objects. If you used `setCollar` with a non-null argument, then you'd extend the object graph to encompass that object as well, and get the exception you expect. – Marko Topolnik Aug 18 '13 at 14:41
  • 1
    @WhoAmI When you write to an `OutputStream` you need to `.close()` it (which does a `.flush()` and potentially more - no need to do both) to ensure that any buffered data is actually written. Without you might never write the last few bytes and therefore read corrupt data. For file output you might also want to sync: http://stackoverflow.com/questions/4072878/i-o-concept-flush-vs-sync – zapl Aug 18 '13 at 14:48
  • @MarkoTopolnik Ok, it means what I understood by the term `ObjectGraph` is totally incorrect. I read all sorts of bookish language and it ha confused me totally :( Can you please elaborate on the term `ObjectGraph` and post it in answer section so that I can close this thread? – WhoAmI Aug 18 '13 at 14:54

2 Answers2

9

Could be because your dog doesn't have a collar!

Try with

Dog dog = new Dog();
dog.setCollar(new Collar());
adarshr
  • 61,315
  • 23
  • 138
  • 167
  • 1
    Interesting. So serialization is about instantiated classes, not their declarations. In retrospect, this makes sense since we could replace Collar with Accessory, and have Collar and FoodBowl being implementers of Accessory. Accessory isn't worth jack for serialization - we need the actual concrete classes. – Tony Ennis Aug 18 '13 at 14:12
2

It appears that you had a misunderstanding of the concept of object graph. In this graph, the nodes are instances (not classes) and the edges are formed from values of reference-typed instance variables.

Applied to your example,

Dog dog = new Dog();

creates an object graph consisting of a single node, the Dog instance. The collar variable is null so its value doesn't form an edge no another node. But, if you add a line such as

dog.setCollar(new Collar());

now your object graph contains two nodes, connected by the edge formed by the value in the collar instance variable.

Now, all this applied to serialization means that your posted example is serializing the one-node object graph, whose all nodes are serializable, but if you added a collar, that graph would contain a non-serializalbe node and you would get the exception you expect.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436