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

Является ли подкласс класса "Сериализуемый" автоматически "Сериализуемым"?

Я хотел спросить, реализует ли дочерний элемент родителя, который реализует интерфейс Serializable, интерфейс Serializable или, другими словами, может быть сериализован этот ребенок?

4b9b3361

Ответ 1

Я хотел спросить, реализует ли потомок родителя, который реализует интерфейс "Сериализуемый", интерфейс "Сериализуемый", или, другими словами, этот потомок может быть сериализован?

Ответ на первую часть - Да. Это является естественным следствием наследования Java.

Ответ на вторую часть не всегда!

Учти это:

public class Parent implements Serializable {
    private int i;
    // ...
}

public class Child extends Parent {
    private final Thread t = new Thread();   // a non-serializable object
    // ...
}

Экземпляр Parent может быть сериализован, но экземпляр Child не может... потому что у него есть атрибут, тип которого (Thread) не сериализуем.

(Теперь, если t был объявлен как transient, или если Child избегал использования механизма сериализации по умолчанию, Child мог бы быть сериализуемым. Но я хочу сказать, что сериализуемость является эмерджентным свойством, а не наследуемым свойством.)

Ответ 2

Да. Если родитель реализует Serializable, то любые дочерние классы также Serializable.

static class A implements Serializable {
}

static class B extends A {
}

public static void main(String[] args) {
    Serializable b = new B(); // <-- this is a legal statement. 
}

B также реализует Serializable.

Ответ 3

Краткий ответ: Да, если родительский класс сериализован, то дочерний класс автоматически сериализуется.

Длинный ответ:

  1. Если Родительский класс является Сериализуемым, то дочерний класс по умолчанию Сериализуем. JVM проверяет, реализует ли родительский класс Serializable, и если да, то также считает, что дочерний класс также сериализуем. Следовательно, Сериализация является наследуемым понятием, которое приходит от родителя к ребенку.

    открытый класс ParentSerializableNotChild {

        public static void main(String[] args) throws Exception{
            Child chileSerialize = new Child();
            //Serialization
            FileOutputStream fos = new FileOutputStream("test.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(chileSerialize);
            FileInputStream fis = new FileInputStream("test.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            Child childDeserialize = (Child) ois.readObject();
            System.out.println(childDeserialize.i + "---" + childDeserialize.j); //10---20      
        }
    }
    
    class Parent implements Serializable{
        int i = 10;
    }
    
    class Child extends Parent{
        int j = 20;
    }
    
  2. Если родительский класс не сериализуем, то и дочерний класс может быть сериализован. Наилучшим примером этого является класс Object, класс Object не реализует Serializable, но любой класс, являющийся дочерним по отношению к классу Object, может реализовать Serializable.

    открытый класс ChildSerializedParentNot {

        public static void main(String[] args) throws Exception{
            Dogy d = new Dogy();
            d.i = 888;
            d.j = 999;      
            FileOutputStream fos = new FileOutputStream("inheritance.ser");
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            System.out.println("Serializing");
            oos.writeObject(d);
            FileInputStream fis = new FileInputStream("inheritance.ser");
            ObjectInputStream ois = new ObjectInputStream(fis);
            System.out.println("Deserializing");
            Dogy d2 = (Dogy) ois.readObject();
            System.out.println(d2.i + "-----" + d2.j);
        }
    }
    class Animal{
        int i = 10;
        Animal(){
            System.out.println("Parent class cons");
        }
    }
    class Dogy extends Animal implements Serializable{
        Dogy(){
             System.out.println("Child class constructor");
         }
         int j = 20;
    }
    

Выход:
Родительский класс минусы
Конструктор дочернего класса
Сериализация
десериализации
Родительский класс минусы
10 999 -----

Сверху, есть 3 случая, когда ребенок сериализуется, но не является родителем.

Случай 1: во время сериализации JVM проверяет, поступает ли какая-либо переменная экземпляра из не сериализованного родительского класса. Если это так, то родительский класс не сериализуем и его переменная экземпляра участвует в сериализации, тогда jvm игнорирует значение переменной экземпляра и сохраняет значение по умолчанию в файле. (В приведенном выше примере, я хранится как 0 в файле).

Случай 2: во время десериализации JVM проверяет, поступает ли какая-либо переменная экземпляра из не сериализованного родительского класса. Если это так, JVM запустит INSTANCE CONTROL FLOW, и первоначальное значение объекта будет восстановлено.

ПОТОК КОНТРОЛЯ ИНСТАНЦИИ (короче) http://java2bigdata.blogspot.in/2015/05/instance-control-flow-in-java.html:
1. Идентификация члена инстанции.
2. Выполнение назначения и создания экземпляра переменной экземпляра.
3. Исполнение конструктора.

Случай 3: Поскольку в потоке управления экземпляра выполняется конструктор. Следовательно, в случае не сериализованного родителя вызывается конструктор без аргументов, этот конструктор может быть предоставлен пользователем или создан jvm. Если нет конструктора без аргументов, это приведет к InvalidClassException.

Ответ 4

Нам не нужен конструктор no-arg, а родительский сериализуем.

Но когда дочерний объект сериализуется, а не родительский, мы должны иметь no-arg const в родительском для установки значений по мере необходимости во время де-сериализации, но в противном случае мы будем иметь значения по умолчанию.