Государственный


Ввод/вывод сложных объектов



бет16/25
Дата05.04.2024
өлшемі4.07 Mb.
#497748
1   ...   12   13   14   15   16   17   18   19   ...   25
Java. Потоки ввода-вывода. Работа с файлами. Кравчук А.С., Кравчук А.И., Кремень Е.В

Ввод/вывод сложных объектов


Методы writeObject() и readObject() просты в использовании, но содержат достаточно сложную логику управления объектами. Если поля класса являются примитивными значениями, то никаких дополнительных усилий при их использовании не понадобится. На практике очень часто многие объекты содержат в качестве полей ссылки на другие объекты. Если с помощью методов readObject() и readObject() нужно восстановить или записать объект из или в поток, они должны быть в состоянии восстановить или записать все объекты, на которые ссылается исходный объект. Эти дополнительные объекты могут иметь свои собственные ссылки и т.д. В этой ситуации readObject() (или writeObject()) проходит через всю сеть ссылок на объекты и восстанавливает (или записывает) все объекты в этой сети в поток.
Таким образом, один вызов метода writeObject() может привести к записи в поток большого количества объектов.
Это показано на следующем рисунке 1, где writeObject() вызывается для записи одного объекта с именем a. Этот объект содержит ссылки на объекты b и c, а b содержит ссылки на d и e . При вызове writeObject(a) записывается не только a, но и все объекты, необходимые для воссоздания a, поэтому остальные четыре объекта также записываются. Когда a считывается обратно с помощью readObject(), остальные четыре объекта также считываются, и все исходные ссылки на объекты сохраняются.




Рисунок 1 - Схема сериализации/десериализации объекта, водержащего ссылки на другие объекты




Замечание.
Графом называется система объектов произвольной природы (вершин) и парных связей (ребер), соединяющих некоторые пары этих объектов (вершин).

Как видно из рисунка 1, в процессе сериализации вместе с сериализуемым объектом сохраняется его граф объектов. Т.е. все связанные с этим объектом, объекты других классов так же будут сериализованы вместе с ним. А значит, все связанные с этим объектом, объекты других классов, которые будут сериализованы должны так же, реализовывать интерфейс Serializable.


Пример.


Результат работы программы:





В данном случае в класс Person добавлено поле address, являющее ссылкой на объект класса Address. Оба класса и Person, и Address реализуют интерфейс Serializable. Объекты обоих классов сериализуются, т. е. ссылки на другие объекты (напомним, что за исключением transient или static полей) также вызывают запись этих объектов.


Немного изменим предыдущий пример, закомментировав метод
toString() для класса Address:

В этом случае, при выводе будет вызываться метод toString() класса Object, который выводит адрес выделенного под объект участка памяти. Результат работы программы:



Из результатов выполнения программы видно, что при восстановлении объектов, у которых до сериализации была ссылка на один и тот же объект, после сериализации объекты также содержат ссылку на тот же объект. Это видно по одинаковым ссылкам в объектах до и после восстановления.




Замечание.
Отметим, что, объекты дочерних классов, которые не являются сериализуемыми, но базовые классы которых сериализуемы, могут быть сериализуемыми. В этом случае несериализуемый класс должен иметь конструктор без параметров, чтобы можно было инициализировать его поля.




Достарыңызбен бөлісу:
1   ...   12   13   14   15   16   17   18   19   ...   25




©dereksiz.org 2024
әкімшілігінің қараңыз

    Басты бет