Хотя решил задачу, не понимаю 2 важных детали:
- 1 почему Solution должен реализовывать интерфейс Serializable? Я воспринимал Solution и его psvm, как просто среду для запуска программы...
- 2 класс A - предок класса B и класс A НЕ реализует интерфейс Serializable. Мы хотим сериализовать доставшиеся B по наследству от класса A поля - зачем A пустой констуктор?
Di
38 уровень
2 БОЛЬШИХ НЕПОНЯТНЫХ ВОПРОСА
Решен
Комментарии (20)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
kto_toExpert
8 сентября 2018, 17:38
В смысле вы воспринимали класс и его майн метод просто как среду для запуска программы, класс и главный метод это неотъемлемая часть самой программы. Кидайте код прямо в вопрос! И указывайте уже по коду что вам непонятно
0
Di
8 сентября 2018, 18:41решение
+3
Di
8 сентября 2018, 18:41
Ведь здесь Solution сам не сериализуется, зачем ему тогда поддерживать интерфейс Serializable?
0
kto_toExpert
8 сентября 2018, 18:46
Да, тут оно не обязательно, а кто добавил интерфейс? Вы или так было дано?
0
Di
8 сентября 2018, 18:59
Без него выходит в консоль ошибка, попробуйте
0
kto_toExpert
8 сентября 2018, 19:30
Зачем?
0
kto_toExpert
8 сентября 2018, 19:34
Без default метода всё норм работает. Как вариант, программе нужно знать что класс A и B — внутренние классы класса Solution, по этому он требует Serializable для Solution
0
Di
8 сентября 2018, 19:36
А вот это очень похоже на правду. Логично - для сериализации внутреннего класса внешний класс тоже должен поддерживать сериализацию. Спасибо!
0
--------Master
8 сентября 2018, 20:05
В данном случае поддержка сериализации нужна внешнему классу только для корректной работы метода defaultWriteObject, но он в данной задаче вообще не нужен - по сути, это выполнение обычной сериализации, а твоя задача - как раз написать свой вариант, а не использовать дефолтный.
+1
Di
9 сентября 2018, 10:30
Кажется картинка сложилась:
Методы private void writeObject(ObjectOutputStream out) и readObject(ObjectInputStream in) используются для организации нестандартной сериализации, когда, в частности, нужно сериализовать поле из класс-родителя, который сам сериализацию НЕ поддерживает.
Для этого можно пойти 2 путями:
- либо сделать сериализуемым весь внешний класс Solution, потому что именно он ответственен за вызов метода out.defaultWriteObject(); и после этого сериализовать поле nameA внутри writeObject() напрямую -> {out.writeObject(nameA);}
- либо просто объявляем внутри класса B методы private void writeObject() и private void readObject(), НЕ вызываем внутри них out.defaultWriteObject(); и in.defaultReadObject(); и как следствие не нужно сериализовать класс Solution. ВМЕСТО ЭТОГО сериализуем поля напрямую - out.writeObject(nameA); out.writeObject(nameB); - и потом также считываем.
+4
Di
9 сентября 2018, 11:13
Егор, подскажите, я правильно понял?
0
--------Master
9 сентября 2018, 12:27
Да, получается так. Для наглядности еще можно выполнить сериализацию обоими способами (defaultWriteObject с Solution implements Serializable и просто writeObject для В) в файлы и сравнить содержимое при равном результате - возможности считывания содержимого объекта класса В со значениями полей))
0
Di
9 сентября 2018, 14:29
Да, проверил - так и есть.
Остался лишь один вопрос - зачем классу A пустой констуктор?
0
--------Master
9 сентября 2018, 14:39
Конструктор по умолчанию ("пустой") нужен классу В для десериализации методом defaultWriteObject, а чтобы создать такой конструктор в классе В, его нужно унаследовать из класса А. Если убрать implements Serializable у класса Solution, то и конструктор по умолчанию не нужен
0
Di
10 сентября 2018, 00:33
Спасибо! Вроде разобрался.
0
Игорь
12 января 2019, 11:25
Убрал implements Serializable у класса Solution и defaultWriteObject / defaultReadObject в методах класса B - все равно без без конструктора по умолчанию в классе A не работает.
0
Константин
17 января 2019, 14:19
Повторю вопрос Игоря, так как та же фигня:
Убрал implements Serializable у класса Solution и defaultWriteObject / defaultReadObject в методах класса B - все равно без без конструктора по умолчанию в классе A не работает.
0
--------Master
17 января 2019, 14:49
Не проще оформить полноценный вопрос с полноценным прикреплением кода, чем гадать, что в с Игорем откуда поубирали и что где в итоге не работает? ))
0
Николай Довгаль
29 января 2019, 00:33
Разница между Serializable и Externalizable заключается не только в «расширенном» доступе для программиста и возможностb более гибко управлять процессом, но и в самом процессе. Прежде всего, в механизме десериализации.
При использовании Serializable под объект просто выделяется память, после чего из потока считываются значения, которыми заполняются все его поля.
Если мы используем Serializable, конструктор объекта не вызывается! Вся работа производится через рефлексию (Reflection API, который мы мельком упоминали в прошлой лекции).
В случае с Externalizable механизм десериализации будет иным. В начале вызывается конструктор по умолчанию. И только потом у созданного объекта UserInfo вызывается метод readExternal(), который и отвечает за заполнение полей объекта.
Именно поэтому любой класс, имплементирующий интерфейс Externalizable, обязан иметь конструктор по умолчанию.
А как раз private void writeObject это часный случай Externalizable
А нашем случае запись super() говорит о том что конструктор используется класса родителя и потму в class A должен быть "конструктор по умолчанию".
Я так понял :)
источник
+1
Татьяна
30 ноября 2019, 09:00
Была где-то примерно такая фраза: при сериализации вызывается пустой конструктор НЕсериалируемого класса родителя
+1