Подтвердить что ты не робот

Как называются конструкторы во время сериализации и десериализации?

Как конструкторы вызываются при сериализации и десериализации

  • Когда есть один класс, реализующий сериализуемый?
  • Когда есть отношения parent/child, и только child реализует сериализуемое?
  • Когда существуют отношения родительские/дочерние, а родительский и дочерний объекты реализуются сериализуемыми?
4b9b3361

Ответ 1

Пример:

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;
    }
}

}

Вывод:

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

Итак, если вы десериализовали свой объект, его конструкторы не вызываются, но будет вызываться конструктор по умолчанию его родителя. И не забывайте: весь ваш сериализуемый объект должен иметь стандартный конструктор без параметров.

Ответ 3

  • Если мы должны быть точными, нет такой вещи, как "один класс". Каждый объект в Java расширяет класс Object, будь то прямой суперкласс или косвенный корень его иерархии. Таким образом, никакие конструкторы не будут запускаться, но притворяясь, что это так, тогда мы не воссоздаем определенный объект, мы просто создаем новый.

  • Когда есть отношения между родителями и дочерними элементами, это зависит от того, является ли родительский Serialable или нет. Если родитель НЕ сериализуется, супер конструктор будет работать! Если оба родителя и ребенка сериализуемы, то не вызываются конструкторы.

Дополнительная информация?

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

Ответ 4

Как конструкторы вызываются при сериализации и десериализации

  • Когда существует один класс, реализующий сериализуемый?

  • Когда существуют отношения родительские/дочерние, и только дочерние элементы реализуются сериализуемыми?

  • Когда есть отношения parent/child, и оба родителя и дочернего объекта реализуют сериализуемое?

На мой взгляд, ответ на ваш вопрос:

1) Если один класс реализует сериализуемый, и только этот класс не существует родительского класса. Поток конструктора, как конструктор по умолчанию, будет вызовом родительского класса, который не реализуется сериализуемым. в этом случае это класс Object. поэтому конструктор No-arg класса Object будет запускаться и будет создавать объект-заглушку, а при вызове поля readObject() будет задано отражение и данные, которые сохраняются в памяти или файле.

2), если только дочерний реализует сериализуемый, тогда поток будет проходить до базового класса, который не является сериализуемым. если базовый класс dierect не сериализуется тогда (этот класс должен иметь конструктор NO-Arg) В этом случае конструктор NO-Arg будет запускаться для базового класса.

3), если все родители сериализованы, то поток перейдет к классу Object, а конструктор No-Arg будет запущен класса Object.

Примечание. Но вы можете сериализовать, реализуя внешний интерфейс, тогда конструктор по умолчанию (NO-ARG) будет вызываться только этим классом только из родительского класса в процессе десериализации.

Ответ 5

Прежде всего во время десериализации ни один вызываемый конструктор, все значения поля будут установлены отражением.

Если вы помечаете свой класс как Serializable, чем JVM, установите значение поля путем отражения во время Deserialization, и после этого JVM ищет суперкласс, и если это не будет помечено как Serializable, то конструктор по умолчанию вызовет, а затем вызовет следующий супер класс и т.д.

взгляните на этот сценарий:

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");
    }
}