Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Deserialization works?

As far as my understanding goes constructor of class whose Object is serialized is not called but the no-arg constructor of 1st non serializable constructor. Now consider following code

public class SerializeDemo implements Serializable {

private String name;
int age;    //default 0

public SerializeDemo(String name, boolean setAge){
    this.name = name;
    if(setAge){
        this.age = 18;
    }
}

@Override
public String toString() {
    return "Name is " + name + " and age is " + age;
}

public static void main(String args[]) throws IOException, ClassNotFoundException {

    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("//home//aniket//Desktop//serializedObjects.txt")));
    ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("//home//aniket//Desktop//serializedObjects.txt")));
    SerializeDemo sd = new SerializeDemo("Test",true);
    System.out.println("Before Serialization : " + sd);
    oos.writeObject(sd);
    SerializeDemo sdCopy = (SerializeDemo)ois.readObject();
    System.out.println("After Deserialization : " + sdCopy);
}
}

and the output is(as expected)

Before Serialization : Name is Test and age is 18
After Deserialization : Name is Test and age is 18

Now the the non serializable super class having no-arg constructor is Object(Correct me if I am wrong). So basically SerializeDemo constructor is not called.

Now when the Object is created during deserialization it will try to rebuild the instance state. So it will set age to 18.

Question is how?

I have deliberately not provided the setter. Nor as per above discussion it's constructor is called. So how is it set?(Same goes for name as well)

like image 819
Aniket Thakur Avatar asked Jan 07 '14 07:01

Aniket Thakur


2 Answers

You can take a look at ObjectInputStream source code. It uses reflection, it creates an object, reads fields from stream, and sets object's fields using reflection. You can run your code in a debugger and go step by step exactly to the line where age is set.

like image 166
Evgeniy Dorofeev Avatar answered Sep 19 '22 15:09

Evgeniy Dorofeev


Now the the non serializable super class having no-arg constructor is Object.

Correct.

So basically SerializeDemo constructor is not called.

Correct.

Now when the Object is created during deserialization it will try to rebuild the instance state. So it will set age to 18.

Correct.

Question is how?

Reflection ... with access checks turned off.

The class descriptor in the serialized class gives the name and type of all of the serialized fields. The Class object defines Field objects for the actual class. The deserialization code matches the available serialized fields to the Field objects, and then uses Field.set(...) methods to set the field values.

(In fact, this is an implementation detail, but that's my understanding of how it works in current generation JVMs. You can always check the source code ...)

like image 44
Stephen C Avatar answered Sep 18 '22 15:09

Stephen C