Как называются конструкторы во время сериализации и десериализации? - PullRequest
49 голосов
/ 15 ноября 2011

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

  1. Когда существует один класс, реализующий сериализуемый?
  2. Когда есть отношения родитель / потомок, и только потомки реализуют сериализуемый?
  3. Когда есть отношения родитель / потомок, и оба родительских и дочерних объекта реализуют сериализуемый?

Ответы [ 6 ]

43 голосов
/ 15 ноября 2011

Во время десериализации доступный конструктор по умолчанию вызывается для первого класса в иерархии наследования, который не реализует Serializable.

> Сериализуемый класс должен иметь доступ к конструктору без аргументов своего первого несериализуемого суперкласса

30 голосов
/ 15 ноября 2011

Пример:

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

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

6 голосов
/ 15 декабря 2017

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

Если вы пометите свой класс как Serializable, чем JVM, установите значение поля путем отражения во время десериализации, и после этого 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");
    }
}
6 голосов
/ 03 декабря 2014

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

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

  2. Когда есть отношения родитель / потомок, и только потомки реализуют сериализуемый?

  3. Когда есть отношения родитель / потомок, и родитель и потомок реализуют сериализуемый?

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

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

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

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

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

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

  2. При наличии родительских / дочерних отношений это зависит от того, является ли родитель Сериализуемым или нет. Если родитель НЕ сериализуем, супер конструктор запустится! Если и родитель, и потомок являются сериализуемыми, тогда никакие конструкторы не вызываются.

Подробнее?

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

0 голосов
/ 07 апреля 2018

Процесс десериализации не использует конструктор объекта - объект создается без конструктора и инициализируется с использованием сериализованных данных экземпляра.Единственное требование к конструктору для класса, реализующего Serializable, заключается в том, что первый несериализуемый суперкласс в его иерархии наследования должен иметь конструктор без аргументов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...