How are constructors called during serialization and deserialization?

JavaSerialization

Java Problem Overview


How are the constructors called during serialization and deserialization

  1. When there is one class implementing serializable?
  2. When there is parent/child relationship and only child implements serializable?
  3. When there is parent/child relationship and both parent and child implements serializable?

Java Solutions


Solution 1 - Java

During deserialization the accessible default constructor is called for the first class in the inheritance hierarchy that does not implement Serializable.

> A Serializable class must have access to the no-arg constructor of its first nonserializable superclass

Solution 2 - Java

Example:

 public class ParentDeserializationTest {

    public static void main(String[] args){
        try {
            System.out.println("Creating...");
            Child c = new Child(1);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            c.field = 10;
            System.out.println("Serializing...");
            oos.writeObject(c);
            oos.flush();
            baos.flush();
            oos.close();
            baos.close();
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            System.out.println("Deserializing...");
            Child c1 = (Child)ois.readObject();
            System.out.println("c1.i="+c1.getI());
            System.out.println("c1.field="+c1.getField());
        } catch (IOException ex){
            ex.printStackTrace();
        } catch (ClassNotFoundException ex){
            ex.printStackTrace();
        }
    }

    public static class Parent {
        protected int field;
        protected Parent(){
            field = 5;
            System.out.println("Parent::Constructor");
        }
        public int getField() {
            return field;
        }
    }

    public static class Child extends Parent implements Serializable{
        protected int i;
        public Child(int i){
            this.i = i;
            System.out.println("Child::Constructor");
        }
        public int getI() {
            return i;
        }
    }
}

Output:

Creating...
Parent::Constructor
Child::Constructor
Serializing...
Deserializing...
Parent::Constructor
c1.i=1
c1.field=5

So if you deserialized your object, its constructors doesn't called, but default constructor of its parent will be called. And don't forget: all your serializable object should have a standard constructor without parameters.

Solution 3 - Java

First of all at the time of Deserialization no any construtor called, all field's value will be set by reflection.

If you mark your class as Serializable than JVM set the field's value by reflection at the time of Deserialization and after that JVM looks for it's super class and if that is not marked as Serializable then default constructor will call and then call next super class and so on.

take a look for this scenario :

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Test {

	public static void main(String...strings) throws IOException, ClassNotFoundException {
		Employee emp = new Employee();
		emp.companyName = "XYZ";
		emp.employeeName = "ABC";
		
		getSirielization(emp);
		Employee em = (Employee) getDeSirielization();
		System.out.println(em.companyName+" "+em.employeeName);
		
	}
	
	public static void getSirielization(Object object) throws IOException {
	
		File f = new File("/home/server/ironman/serializedFile.txt");
		FileOutputStream fo = new FileOutputStream(f);
		ObjectOutputStream oob = new ObjectOutputStream(fo);
		oob.writeObject(object);
	}
	
	public static Object getDeSirielization() throws IOException, ClassNotFoundException {
		
		File f = new File("/home/server/ironman/serializedFile.txt");
		FileInputStream fo = new FileInputStream(f);
		ObjectInputStream oob = new ObjectInputStream(fo);
		Object object = oob.readObject();
		return object;
	}
}

class Company {
	String companyName;
	
	public Company() {
		System.out.println("Company-Default");
	}
	
}

class Employee extends Company implements Serializable {

	private static final long serialVersionUID = -3830853389460498676L;
	
	String employeeName;
	
	public Employee() {
		
		System.out.println("hello2");
	}
}

Solution 4 - Java

  1. If we have to be precise, there is no such thing as "one class". Every object in Java extends class Object, whether as a direct superclass or indirect root of its hierarchy. So no constructors will run, but pretending that was the case, then we are not re-creating a certain object, we are just creating a new one.

  2. When there is parent/child relationship it depends on whether the parent is Serialiable or not. If the parent is NOT serializable, the super constructor will run! If both parent and child are serializable then no constructors are called.

More info?

http://www.java-questions.com/Serialization_interview_questions.html

Solution 5 - Java

> How are the constructors called during serialization and deserialization

> 1. When there is one class implementing serializable?

> 2. When there is parent/child relationship and only child implements serializable?

> 3. When there is parent/child relationship and both parent and child implements serializable?

In my opinion the answer of your question is :

  1. If one class is implementing serializable and only that class is there no parent class is there. constructor flow is like default constructor will be call of the parent class who is not implemented serializable. in this case it is Object class. so No-arg constructor of Object class will run and will create dummy object and while calling readObject() field will be set by reflection and data which is saved in memory or file.

  2. if only child implements serializable then flow will goes till the base class which is not serializable. if dierect base class is not serialized then (that class should have NO-Arg constructor) NO-Arg constructor will run for base class in this case.

  3. if all the parents are serialized then flow will goes to Object class and No-Arg constructor will run of Object class.

Note : But you can serialize by implementing externalizable interface then default constructor (NO-ARG) will be called of that class only not of parent class on deserialization process.

Solution 6 - Java

The deserialization process does not use the object's constructor - the object is instantiated without a constructor and initialized using the serialized instance data. The only requirement on the constructor for a class that implements Serializable is that the first non-serializable superclass in its inheritence hierarchy must have a no-argument constructor.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRekhaView Question on Stackoverflow
Solution 1 - JavaszhemView Answer on Stackoverflow
Solution 2 - JavaDenis LoshkarevView Answer on Stackoverflow
Solution 3 - Javaritesh9984View Answer on Stackoverflow
Solution 4 - JavaMechkovView Answer on Stackoverflow
Solution 5 - JavaPrashantView Answer on Stackoverflow
Solution 6 - JavaKingshuk SahaView Answer on Stackoverflow