Чтение онлайн

на главную - закладки

Жанры

Программирование на Java
Шрифт:

Выполнение этой программы приведет к выводу на экран примерно следующего:

Constructing line: 1

Constructing line: 2

line 1 = Line@7d39

line 2 = Line@4ec

Read objects:

Line: 1

Object reference: Line@331e

from point (1.0,1.0) reference=Point@36bb

to point (2.0,2.0) reference=Point@386e

Line: 2

Object reference: Line@6706

from point (2.0,2.0) reference=Point@386e

to point (3.0,3.0) reference=Point@68ae

Line: 1

Object reference: Line@331e

from point (1.0,1.0) reference=Point@36bb

to point (2.0,2.0) reference=Point@386e

Пример 15.13.

Из примера видно, что после восстановления у линий сохраняется общая точка, описываемая одним и тем же объектом (хеш-код 386e ).

Третий записанный объект идентичен первому, причем, совпадают даже объектные ссылки. Несмотря на то, что при записи третьего объекта значение index было изменено на 3, в десериализованном объекте оно осталось равным 1. Так произошло потому, что объект, описывающий первую линию, уже был задействован в сериализации и, встретившись во второй раз, повторно записан не был.

Чтобы указать, что сеанс сериализации завершен, и получить возможность передавать измененные объекты, у ObjectOutputStream нужно вызвать метод reset. В рассматриваемом примере для этого достаточно убрать комментарий в строке

//oos.reset;

Если теперь запустить программу, то можно увидеть, что третий объект получит номер 3.

Constructing line: 1

Constructing line: 2

line 1 = Line@ea2dfe

line 2 = Line@7182c1

Read objects:

Line: 1

Object reference: Line@a981ca

from point (1.0,1.0) reference=Point@1503a3

to point (2.0,2.0) reference=Point@a1c887

Line: 2

Object reference: Line@743399

from point (2.0,2.0) reference=Point@a1c887

to point (3.0,3.0) reference=Point@e7b241

Line: 3

Object reference: Line@67d940

from point (1.0,1.0) reference=Point@e83912

to point (2.0,2.0) reference=Point@fae3c6

Пример 15.14.

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

Расширение стандартной сериализации

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

private void writeObject(

java.io.ObjectOutputStream out)

throws IOException;

private void readObject(

java.io.ObjectInputStream in)

throws IOException, ClassNotFoundException;

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

out.defaultWriteObject;

Этот метод запишет все не- transient и не- static поля в поток данных.

В

свою очередь, при десериализации метод readObject должен считать данные из потока in (также полученного в качестве аргумента) и восстановить значения полей класса. При реализации этого метода можно обратиться к стандартному механизму с помощью метода:

in.defaultReadObject;

Этот метод считывает описание объекта из потока и присваивает значения соответствующих полей в текущем объекте.

Если же процедура сериализации в корне отличается от стандартной, то для таких классов предназначен альтернативный интерфейс java.io.Externalizable.

При использовании этого интерфейса в поток автоматически записывается только идентификация класса. Сохранить и восстановить всю информацию о состоянии экземпляра должен сам класс. Для этого в нем должны быть объявлены методы writeExternal и readExternal интерфейса Externalizable. Эти методы должны обеспечить сохранение состояния, описываемого полями самого класса и его суперкласса.

При восстановлении Externalizable -объекта экземпляр создается путем вызова конструктора без аргументов, после чего вызывается метод readExternal.

Метод writeExternal имеет сигнатуру:

void writeExternal(ObjectOutput out)

throws IOException;

Для сохранения состояния вызываются методы ObjectOutput, с помощью которых можно записать как примитивные, так и объектные значения. Для корректной работы в соответствующем методе

void readExternal(ObjectInput in)

throws IOException,ClassNotFoundException;

эти значения должны быть считаны в том же самом порядке.

Классы Reader и Writer и их наследники

Рассмотренные классы – наследники InputStream и OutputStream – работают с байтовыми данными. Если с их помощью записывать или считывать текст, то сначала необходимо сопоставить каждому символу его числовой код. Такое соответствие называется кодировкой.

Известно, что Java использует кодировку Unicode, в которой символы представляются двухбайтовым кодом. Байтовые потоки зачастую работают с текстом упрощенно – они просто отбрасывают старший байт каждого символа. В реальных же приложениях могут использовать различные кодировки (даже для русского языка их существует несколько). Поэтому в версии Java 1.1 появился дополнительный набор классов, основывающийся на типах Reader и Writer. Их иерархия представлена на рис. 15.2.

Эта иерархия очень схожа с аналогичной для байтовых потоков InputStream и OutputStream. Главное отличие между ними – Reader и Writer работают с потоком символов ( char ). Только чтение массива символов в Reader описывается методом read(char[]), а запись в Writer – write(char[]).

В таблице 15.1 приведены соответствия классов для байтовых и символьных потоков.

Рис. 15.2. Иерархия классов Reader и Writer.

Поделиться:
Популярные книги

Эволюционер из трущоб. Том 12

Панарин Антон
12. Эволюционер из трущоб
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Эволюционер из трущоб. Том 12

Взломщик

Грач Игорь
Вселенная EVE Online
Фантастика:
космическая фантастика
6.94
рейтинг книги
Взломщик

Слово президента

Клэнси Том
8. Джек Райан
Детективы:
политические детективы
6.20
рейтинг книги
Слово президента

Тёмный Лорд Поттер

The Santi
Проект «Поттер-Фанфикшн»
Фантастика:
фэнтези
городское фэнтези
5.00
рейтинг книги
Тёмный Лорд Поттер

Ведьмак (сборник)

Сапковский Анджей
Фантастика:
фэнтези
6.67
рейтинг книги
Ведьмак (сборник)

Голубая Сфера

Мак Иван
21. Легенды Вселенной
Фантастика:
боевая фантастика
3.40
рейтинг книги
Голубая Сфера

Я не бог. Книга XXXIV

Дрейк Сириус
34. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не бог. Книга XXXIV

Гильдия

Голотвина Ольга Владимировна
Гильдия
Фантастика:
боевая фантастика
5.25
рейтинг книги
Гильдия

Лэшер

Райс Энн
5. Мэйфейрские ведьмы
Фантастика:
ужасы и мистика
8.32
рейтинг книги
Лэшер

Звезда

Стил Даниэла
Любовные романы:
современные любовные романы
9.11
рейтинг книги
Звезда

Чужак

Листратов Валерий
1. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Чужак

Сотрудник агентства «Континенталь» (Сборник)

Хэммет Дэшилл
Оперативник агентства «Континентал»
Детективы:
крутой детектив
5.00
рейтинг книги
Сотрудник агентства «Континенталь» (Сборник)

Последний герой

Грэйдо Эллениэль и Эстель
2. Последний герой
Фантастика:
фэнтези
юмористическое фэнтези
6.60
рейтинг книги
Последний герой

Гражданская война в Испании. 1936-1939 гг.

Платошкин Николай Николаевич
Научно-образовательная:
история
7.50
рейтинг книги
Гражданская война в Испании. 1936-1939 гг.