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

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

Жанры

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

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

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

подключение к базе данных, в таких случаях нужно устанавливать заново.

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

Для исключения поля объекта из сериализации его необходимо объявить с модификатором transient. Например, следующий класс:

class Account implements

java.io.Serializable {

private String name;

private String login;

private transient String password;

/* объявление других элементов класса

...

*/

}

У такого класса поле password в сериализации участвовать не будет и при восстановлении оно получит значение по умолчанию (в данном случае null ).

Особого внимания требуют статические поля. Поскольку они принадлежат классу, а не объекту, они не участвуют в сериализации. При восстановлении объект будет работать с таким значением static -поля, которое уже установлено для его класса в этой JVM.

Граф сериализации

До этого мы рассматривали объекты, которые имеют поля лишь примитивных типов. Если же сериализуемый объект ссылается на другие объекты, их также необходимо сохранить (записать в поток байт), а при десериализации – восстановить. Эти объекты, в свою очередь, также могут ссылаться на следующие объекты. При этом важно, что если несколько ссылок указывают на один и тот же объект, то этот объект должен быть сериализован лишь однажды, а при восстановлении все ссылки должны вновь указывать на него одного. Например, сериализуемый объект A ссылается на объекты B и C, каждый из которых, в свою очередь, ссылается на один и тот же объект D. После десериализации не должно возникать ситуации, когда B ссылается на D1, а C – на D2, где D1 и D2 – равные, но все же различные объекты.

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

При построении графа может встретиться объект, порожденный от класса, не реализующего интерфейс Serializable. В этом случае сериализация прерывается, генерируется исключение java.io.NotSerializableException.

Рассмотрим пример:

import java.io.;

class Point implements Serializable {

double x;

double y;

public Point(double x, double y) {

this.x = x;

this.y = y;

}

public String toString {

return "("+x+","+y+") reference="+super.toString;

}

}

class Line implements Serializable {

Point point1;

Point point2;

int index;

public Line {

System.out.println("Constructing empty line");

}

Line(Point p1, Point p2, int index) {

System.out.println("Constructing line: " + index);

this.point1 = p1;

this.point2 = p2;

this.index = index;

}

public int getIndex {

return index;

}

public void setIndex(int newIndex) {

index = newIndex;

}

public void printInfo {

System.out.println("Line: " + index);

System.out.println(" Object reference: " + super.toString);

System.out.println(" from point "+point1);

System.out.println(" to point "+point2);

}

}

public class Main {

public static void main(java.lang.String[] args) {

Point p1 = new Point(1.0,1.0);

Point p2 = new Point(2.0,2.0);

Point p3 = new Point(3.0,3.0);

Line line1 = new Line(p1,p2,1);

Line line2 = new Line(p2,p3,2);

System.out.println("line 1 = " + line1);

System.out.println("line 2 = " + line2);

String fileName = "d:\\file"; try {

//

записываем объекты в файл

FileOutputStream os = new FileOutputStream(fileName);

ObjectOutputStream oos = new ObjectOutputStream(os);

oos.writeObject(line1);

oos.writeObject(line2);

// меняем состояние line1 и записываем его еще раз

line1.setIndex(3);

//oos.reset;

oos.writeObject(line1);

// закрываем потоки

// достаточно закрыть только поток-надстройку 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) и вновь сериализуется.

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

Мастер...

Чащин Валерий
1. Мастер
Фантастика:
героическая фантастика
попаданцы
аниме
6.50
рейтинг книги
Мастер...

Жених из гроба

Сотис Майя
1. Гробокопательница
Фантастика:
юмористическое фэнтези
сказочная фантастика
фэнтези
5.00
рейтинг книги
Жених из гроба

Ищу жену с прицепом

Рам Янка
2. Спасатели
Любовные романы:
современные любовные романы
6.25
рейтинг книги
Ищу жену с прицепом

Гримуар тёмного лорда I

Грехов Тимофей
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар тёмного лорда I

Заклятие предков

Прозоров Александр Дмитриевич
3. Ведун
Фантастика:
фэнтези
альтернативная история
8.49
рейтинг книги
Заклятие предков

Крепость над бездной

Лисина Александра
4. Гибрид
Фантастика:
боевая фантастика
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Крепость над бездной

Рота Его Величества

Дроздов Анатолий Федорович
Новые герои
Фантастика:
боевая фантастика
8.55
рейтинг книги
Рота Его Величества

Экспансия: Сотрудничество. Том 5

Белов Артем
5. Планетарный десант
Фантастика:
боевая фантастика
аниме
5.00
рейтинг книги
Экспансия: Сотрудничество. Том 5

Отверженный III: Вызов

Опсокополос Алексис
3. Отверженный
Фантастика:
фэнтези
альтернативная история
7.73
рейтинг книги
Отверженный III: Вызов

Князь Серединного мира

Земляной Андрей Борисович
4. Страж
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Князь Серединного мира

Возвышение Меркурия. Книга 8

Кронос Александр
8. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 8

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

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

Локки 7. Потомок бога

Решетов Евгений Валерьевич
7. Локки
Фантастика:
аниме
эпическая фантастика
фэнтези
5.00
рейтинг книги
Локки 7. Потомок бога

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4