oos.close(); // считываем объекты System.out.println('Read objects:'); FileInputStream is = new FileInputStream(fileName); ObjectInputStream ois = new ObjectInputStream(is); for (int i=0; i<3; i++) { // Считываем 3 объекта Line line = (Line)ois.readObject(); line.printInfo(); } ois.close(); } catch(ClassNotFoundException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } } } Пример 15.12.

В этой программе работа идет с классом Line (линия), который имеет 2 поля типа Point (линия описывается двумя точками). Запускаемый класс Main создает два объекта класса Line, причем, одна из точек у них общая. Кроме этого, линия имеет номер (поле index ). Созданные линии (номера 1 и 2) записываются в поток, после чего одна из них получает новый номер (3) и вновь сериализуется.

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

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;

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату