HowToDoInJava

  • Java 8
  • Regex
  • Concurrency
  • Best Practices
  • Spring Boot
  • JUnit5
  • Interview Questions

How Deserialization Process Happen in Java?

By Lokesh Gupta | Filed Under: Serialization

In one of my previous post related to “Implementing Serializable interface in java“, Mr. Bitoo asked a good question “at the time of the deserializtion, how the JVM creates the object without calling the constructor??“. I thought of replying him in same post in a comment, but in another moment I thought of this a very interesting topic which requires a separate detailed article, as well as discussion with you folks. So, here I am starting the discussion with my limited knowledge in this topic and I will encourage you all to put your thoughts/queries so make this topic clear for all of us. Here I begin.

We have already covered many things related to serialization in java, and some stuff related to deserialization in java as well. I will not again re-iterate the same thing again and directly come to main discussion topic i.e. how deserialization works in Java?

Deserialization is the process by which the object previously serialized is reconstructed back into it’s original form i.e. object instance. The input to the deserialization process is the stream of bytes which we get over the other end of network OR we simply read it from file system/database. One question arise immediately, what is written inside this stream of bytes?

Read More: Mini guide for implementing serializable interface

To be very precise, this stream of bytes (or say serialized data) has all the information about the instance which was serialized by serialization process. This information includes class’s meta data, type information of instance fields and values of instance fields as well. This same information is needed when object is re-constructed back to a new object instance. While deserializing an object, the JVM reads its class metadata from the stream of bytes which specifies whether the class of an object implements either ‘Serializable’ or ‘Externalizable’ interface.

Please note that for the deserialization to happen seamlessly, the bytecode of a class, whose object is being deserialized, must be present within the JVM performing deserialization. Otherwise, the ‘ClassNotFoundException’ is thrown. Isn’t it too obvious ??

If instance implements the serializable interface, then an instance of the class is created without invoking it’s any constructor. Really? then how the object is created if not constructor is called?

Let’s look at the bytecode of a simple eprogram:

public class SimpleProgram
{
    public static void main(String[] args)
    {
        System.out.println("Hello World!");
    }
}

Byte code:

public class SimpleProgram extends java.lang.Object{
public SimpleProgram();
  Code:
   0:	aload_0
   1:	invokespecial	#1; //Method java/lang/Object."":()V
   4:	return

public static void main(java.lang.String[]);
  Code:
   0:	getstatic	#2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:	ldc	#3; //String Hello World!
   5:	invokevirtual	#4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:	return
}

Above bytecode looks real stuff, isn’t it? In our first line, we’re going to push a value from the “local variable table” onto the stack. In this case, we’re really only pushing the implicit reference to “this” so it isn’t the most exciting instruction. Second instruction is main thing. It actually invokes the constructor of super most class and in above case it is Object.java. And once the constructor of super most class (i.e. Object in this case) has been called, rest of the code does specific instructions written in code.

Matching to above concept i.e. constructor of super most class, we have similar concept in deserialization. In deserialization process, it is required that all the parent classes of instance should be Serializable; and if any super class in hirarchy is not Serializable then it must have a default constructor. Now it make sense. So, while deserialization the super most class is searched first until any non-serializable class is found. If all super classes are serializable then JVM end up reaching Object class itself and create an instance of Object class first. If in between searching the super classes, any class is found non-serializable then it’s default constructor will be used to allocate an instance in memory.

If any super class of instance to be de-serialized in non-serializable and also does not have a default constructor then the ‘NotSerializableException‘ is thrown by JVM.

Also, before continuing with the object reconstruction, the JVM checks to see if the serialVersionUID mentioned in the byte stream matches the serialVersionUID of the class of that object. If it does not match then the ‘InvalidClassException‘ is thrown.

Read More: SerialVersionUID in java and related fast facts

So till now we got the instance located in memory using one of superclass’s default constructor. Note that after this no constructor will be called for any class. After executing super class constructor, JVM read the byte stream and use instance’s meta data to set type information and other meta information of instance.

After the blank instance is created, JVM first set it’s static fields and then invokes the default readObject() method [if it’s not overridden, otherwise overridden method will be called] internally which is responsible for setting the values from byte stream to blank instance.

Read More: Example code for readObject() and writeObject()

After the readObject() method is completed, the deserialization process is done and you are ready to work with new deserialized instance.

Please post your thoughts/views/queries for this topic in comments area. These are more than welcome.

Happy Learning !!

About Lokesh Gupta

Founded HowToDoInJava.com in late 2012. I love computers, programming and solving problems everyday. A family guy with fun loving nature. You can find me on Facebook, Twitter and Google Plus.

Feedback, Discussion and Comments

  1. Sumant

    February 4, 2019

    Hi,

    I tried creating super class with no default constructor and non-serializable, still my child class deserialize successfully. Can you please explain, how this happen.

    You mention :-

    “In deserialization process, it is required that all the parent classes of instance should be Serializable; and if any super class in hirarchy is not Serializable then it must have a default constructor. Now it make sense. So, while deserialization the super most class is searched first until any non-serializable class is found. If all super classes are serializable then JVM end up reaching Object class itself and create an instance of Object class first. If in between searching the super classes, any class is found non-serializable then it’s default constructor will be used to allocate an instance in memory.”

    Regards,
    Sumant

    Reply
    • Lokesh Gupta

      February 4, 2019

      Please post the code you tried?

      Reply
  2. Sumant

    February 4, 2019

    Hi,

    I tried creating a super class with no default constructor and non-serializable, still I was able to deserialize my child class. Conyou please explain, how is this hapens?

    Reply
    • Lokesh Gupta

      February 4, 2019

      Please post the code you tried?

      Reply
  3. K.Radhakrishnan

    May 17, 2018

    First I would like to appreciate for this nice article and for your nice explanation. I have one doubt regarding how the serial version ids are compared.
    You said,
    “Also, before continuing with the object reconstruction, the JVM checks to see if the serialVersionUID mentioned in the byte stream matches the serialVersionUID of the class of that object. If it does not match then the ‘InvalidClassException‘ is thrown.”
    In the byte stream we have serial version id, assuming i am explicitly mentioned. But it is compared with what?. Does the JVM generate the id even though i already specified while deserialization. I am bit confused there. Could you please explain me, how the serial version ids are compared?

    Reply
  4. Mil

    November 10, 2017

    Hello
    What about Externalizable.when we creat a class that implements Externalizable we must define a no-arg constructor for this class.
    But Externalizable interface implements serializable interface.
    and we know that if a class is serializable its no-arg constructor is not needed to deserialization.then what is the usage of no-arg constructor in Externalizable?
    Thanks

    Reply
  5. Praveen

    March 24, 2017

    Hi Lokesh,

    After reading your article about “How Deserialization Process Happen in Java”, I get confused or you can say get more thoughts to think about deserialization process.

    As per your statements about deserialization process:
    1. Without calling the constructor all deserialization process happens with the help of “metadata exists in byte code”.
    2. While deserialization the super most class is searched first until any non-serializable class is found. If all super classes are serializable then JVM end up reaching Object class itself and create an instance of Object class first.

    So in above two statements one says not calling the constructor and one says calling of super class constructor which not implements serializable. This is only my confusion point.

    After reading this article many times, line by line, below is my understanding about deserialization process.
    Let assume there is a class Test implements Serializable

    For Test class during Deserializtion proces below steps happens.
    Step 1. Super most constructor(not this class constructor as it implements Seriaziable) gets called which not implements serializable. For above class i.e Object class.
    Step 2. And in that reference all values(instance variable value) get omitted for class A from bytecode(metadata).

    Sample Code snippet which I assume which does by JVM, for above two steps will be like this.

    Step 1. Object obj = new Object();
    Step 2. Test test = (Test) obj;
    Step 3. // Values get omitted from byte code into "test" object.
    

    Please validate it and put your thoughts about my understanding.

    Thanks

    Reply
  6. Ramana

    December 15, 2016

    If any super class of instance to be de-serialized in non-serializable and also does not have a default constructor then the ‘NotSerializableException‘ is thrown by JVM.

    This is wrong.. Even In above scenario we are getting InvalidClassException only . plz cehck once..

    Reply
    • Lokesh Gupta

      December 16, 2016

      InvalidClassException is Thrown when the Serialization runtime detects one of the following problems with a Class.

      The serial version of the class does not match that of the class descriptor read from the stream
      The class contains unknown datatypes
      The class does not have an accessible no-arg constructor

      Reference: https://docs.oracle.com/javase/7/docs/api/java/io/InvalidClassException.html

      Reply
  7. sureshkumar

    July 17, 2016

    in java multiple components are distributed across networks and systems.I want to know what exact the components gets distributed in a enterprise applicaion

    Reply
  8. irshad kashmiri

    June 22, 2016

    Hi Lokesh,
    If any class in the inheritance hierarchy is non-serializable then exception non-serializable exception is thrown itself so it does not wait for default presence default constructor to b present .Am i right. second because deserialization is the process to resurrect the object state in the form in which it was saved, so logic says that there is no need to execuete any constructor otherwise it will b entirely new state of object instead of the object which we want to resurrect

    Reply
    • irshad kashmiri

      June 30, 2016

      Sorry i mean not in Hierarchy ,but when a class is having a reference of other class and that class if not serializable then we get compile time Exception.

      Reply
  9. saurabha porwal

    April 19, 2016

    “Also, before continuing with the object reconstruction, the JVM checks to see if the serialVersionUID mentioned in the byte stream matches the serialVersionUID of the class of that object. If it does not match then the ‘InvalidClassException‘ is thrown.”

    This is fine that serialVersionUID in the byte stream but my doubt is how JVM find “serialVersionUID of the class of the object ” at the time of deserialization as we are sending byte stream over the network only.

    Reply
  10. Abhishek Sharma

    January 9, 2016

    Suppose I have a map with Serializable object as its value like this.
    Case 1. public final Map extensions = new HashMap();

    On the other hand I have
    Case 2. public final Map extensions
    and this object in the constructor of the class is initialized like this
    extensions = new HashMap();
    Not 100% sure. Do you think the 2 approaches will have different affect or are they same.

    Reply
    • Abhishek Sharma

      January 9, 2016

      Map is like this
      public final Map extensions = new HashMap ();

      Reply
  11. NJ

    May 28, 2015

    If we have overridden one of method from ObjectInputStream class e.g. readResolve() then at which point of execution will it going to call during deserialization ?

    Reply
  12. Vipin

    April 8, 2015

    class a{
    a(){sysout(“Hello”)}
    }
    class b extends a implements Serializable{
    }
    during de-serialization,it does not call a() constructor.but what do you mean by having this constructor and its use.

    Reply
  13. RS

    March 11, 2015

    “After the blank instance is created, JVM first set it’s static fields and then invokes the default readObject() method [if it’s not overridden, otherwise overridden method will be called] internally which is responsible for setting the values from byte stream to blank instance.”

    How come the static fields are set, when we say that static fields are not serialized?

    Reply
    • Lokesh

      March 15, 2015

      Very good question. As static fields are at class level and not at instance level; and if available in runtime, these static fields are verified and refer the value same as other instances available in runtime. De-serialization starts when JVM start copying values inside readObject() method.

      Reply
  14. Srinivas

    September 30, 2014

    class A{}
    class B extends A implements Serializable{}
    class C extends B{}

    My question is , whether A should implement Serializable interface, as B is implementing it?

    Reply
    • Lokesh

      September 30, 2014

      During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.

      Serialization exception is only thrown if the class being serialized is not serializable. having non-serializable parents is fine (as long as they have a no-arg constructor). Object itself isnt Serializable, and everything extends it.

      Reply
  15. JavaSerial

    August 1, 2014

    So as you said “while deserialization the super most class is searched first until any non-serializable class is found” it means first non serializable parent’s default constructor called by jvm to construct the object.
    But returned object is instance of parent. how do we get actual child object after this call??? still confused.

    Reply
    • Lokesh

      August 1, 2014

      Above process just creates a blank object in memory, as it is the first step even in normal object’s creation. After this, JVM reads meta data information (and field values) from de-serialized data/stream and copy/set it to the new blank instance it created in first step. This meta data holds the information about the actual instance type, and all other parent hirarchy as well.

      Reply
      • JavaSerial

        August 1, 2014

        But blank object in memory is of parent type and de-serialized data/stream is of actual object type. It means jvm copying the childs stream data into blank parent object. then there must be loss of child data. question still in mind is how suddenly parent object converted into child ref ?? How blank object knows about all the fields child object has ? there can be various type of childs available ??

        Reply
        • Lokesh

          August 1, 2014

          It’s all written as metadata. In JVM runtime as well, objects are differentiated based on their metadata information only. JVM maintains and understand this metadata. Using this metadata, JVM is able to identify about actual type of instance.

          Reply
  16. Shriman N K

    July 27, 2014

    Thanks for the reply,
    I would like to know,For an object there will be a unique hashcode.
    In some cases, If i have an hashcode stored, Will I get a Object?

    Reply
    • Lokesh

      July 27, 2014

      Hashcodes are always generated on demand (by calling hashCode() method) by JVM for any/all object instances in runtime. There is no storage concept for hashcodes.

      Reply
  17. AmitP

    July 26, 2014

    Suppose the server is in US and i’m a user in india. So if some data or object from server is serialized and send on my machine. But i don’t have java/jre/jvm on my machine(nor java enabled browser). In this case how will the object or data de-serialization happen on my machine or will it not happen.So exactly who will do deserialization ?

    Reply
    • Lokesh

      July 26, 2014

      In your case de-serialization will not happen. Responsibility of deserialization completely lies with JVM. If you don’t have JVM (read JRE) than you can’t deserialize the class. Period.

      Reply
  18. Shriman N K

    July 25, 2014

    Is there any way of getting object by hashcode?

    Reply
    • Lokesh

      July 25, 2014

      Absolutely no idea what you want to know? Can you please more elaborate your question.

      Reply

Ask Questions & Share Feedback Cancel reply

Your email address will not be published. Required fields are marked *

*Want to Post Code Snippets or XML content? Please use [java] ... [/java] tags otherwise code may not appear partially or even fully. e.g.
[java] 
public static void main (String[] args) {
...
}
[/java]

Help me fight spammers. Solve this simple math. *

Search Tutorials

  • Email
  • Facebook
  • RSS
  • Twitter

Java Serialization Tutorial

  • Serialization – Serializable Interface
  • Serialization – SerialVersionUID
  • Serialization – Externalizable
  • Externalizable vs Serializable
  • Serialization – Java Object to XML
  • Serialization – Deserialization Process
  • Serialization – ReadObject and WriteObject
  • Serialization – Deep Cloning using In-memory Serialization

Popular Tutorials

  • Java 8 Tutorial
  • Core Java Tutorial
  • Java Collections
  • Java Concurrency
  • Spring Boot Tutorial
  • Spring AOP Tutorial
  • Spring MVC Tutorial
  • Spring Security Tutorial
  • Hibernate Tutorial
  • Jersey Tutorial
  • Maven Tutorial
  • Log4j Tutorial
  • Regex Tutorial

Meta Links

  • Advertise
  • Contact Us
  • Privacy policy
  • About Me

Copyright © 2016 · HowToDoInjava.com · All Rights Reserved. | Sitemap