How are constructors called during serialization and deserialization?

前端 未结 6 1395
感情败类
感情败类 2020-11-28 06:16

How are the constructors called during serialization and deserialization

  1. When there is one class implementing serializable?
  2. When there is parent/child
相关标签:
6条回答
  • 2020-11-28 06:27

    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.

    0 讨论(0)
  • 2020-11-28 06:32

    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");
        }
    }
    
    0 讨论(0)
  • 2020-11-28 06:32

    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.

    0 讨论(0)
  • 2020-11-28 06:38
    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

    0 讨论(0)
  • 2020-11-28 06:43

    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

    0 讨论(0)
  • 2020-11-28 06:53

    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.

    0 讨论(0)
提交回复
热议问题