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

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

Жанры

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

С другой стороны, не меньшей проблемой является восстановление объекта. Как говорилось раньше, объект может быть создан только вызовом его конструктора. У класса, от которого порожден десериализуемый объект, может быть несколько конструкторов, причем, некоторые из них, или все, могут иметь аргументы. Какой из них вызвать? Какие значения передать в качестве аргументов?

После создания объекта необходимо установить считанные значения его полей. Однако многие классы имеют специальные set -методы для этой цели. В таких методах могут происходить проверки, могут меняться значения вспомогательных полей. Пользоваться ли этими методами? Если их несколько, то как выбрать правильный и какие параметры ему передать? Снова возникает проблема работы с недоступными полями, полученными по наследству. Как же в стандартном механизме сериализации решены все эти вопросы?

Во-первых, рассмотрим подробнее работу с интерфейсом Serializable. Заметим, что класс Object не реализует этот интерфейс. Таким образом, существует два варианта – либо сериализуемый класс наследуется от Serializable -класса, либо нет. Первый вариант довольно прост. Если родительский класс уже реализовал интерфейс Serializable, то наследникам это свойство передается автоматически, то есть все объекты, порожденные от такого класса, или любого его наследника, могут быть сериализованы.

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

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

// Родительский класс, не реализующий Serializable

public class Parent {

public String firstName;

private String lastName;

public Parent {

System.out.println("Create Parent");

firstName="old_first"; lastName="old_last";

}

public void changeNames {

firstName="new_first"; lastName="new_last";

}

public String toString {

return super.toString+",first="+firstName+",last="+lastName;

}

}

// Класс Child, впервые реализовавший Serializable

public class Child extends Parent implements Serializable {

private int age;

public Child(int age) {

System.out.println("Create Child");

this.age=age;

}

public String toString {

return super.toString+",age="+age;

}

}

// Наследник Serializable-класса

public class Child2 extends Child {

private int size;

public Child2(int age, int size) {

super(age);

System.out.println("Create Child2");

this.size=size;

}

public String toString {

return super.toString+",size="+size;

}

}

// Запускаемый класс для теста

public class Test {

public static void main(String[] arg) {

try {

FileOutputStream fos=new FileOutputStream("output.bin");

ObjectOutputStream oos=new ObjectOutputStream(fos);

Child c=new Child(2);

c.changeNames;

System.out.println(c);

oos.writeObject(c);

oos.writeObject(new Child2(3, 4));

oos.close;

System.out.println("Read objects:");

FileInputStream fis=new FileInputStream("output.bin");

ObjectInputStream ois=new ObjectInputStream(fis);

System.out.println(ois.readObject);

System.out.println(ois.readObject);

ois.close;

}

catch (Exception e) {

// упрощенная обработка для краткости

e.printStackTrace;

}

}

}

Пример 15.10.

В этом примере объявлено 3 класса. Класс Parent не реализует Serializable и, следовательно, не может быть сериализован. В нем объявлено 2 поля, которые при создании получают значения, содержащие слово "old" ("старый"). Кроме этого, объявлен метод, позволяющий модифицировать эти поля. Он выставляет им значения, содержащие слово "new" ("новый’). Также переопределен метод toString, чтобы дать возможность узнать значения этих полей.

Поскольку класс Parent имеет доступный конструктор по умолчанию, его наследник может реализовать интерфейс Serializable. Обратите внимание, что у самого класса Child такого конструктора уже нет. Также объявлено поле и модифицирован метод toString.

Наконец, класс Child2 наследуется от Child, а потому автоматически является допустимым для сериализации. Аналогично, имеет новое поле, значение которого отображает toString.

Запускаемый класс Test сериализует в файл output.bin два объекта. Обратите внимание, что у первого из них предварительно вызывается метод changeNames, который модифицирует значения полей, унаследованных от класса Parent.

Результат выполнения примера:

Create Parent

Create Child

Child@ad3ba4,first=new_first,last=new_last,age=2

Create Parent

Create Child

Create Child2

Read objects:

Create Parent

Child@723d7c,first=old_first,last=old_last,age=2

Create Parent

Child2@22c95b,first=old_first,last=old_last,age=3,size=4

Пример 15.11.

Во всех конструкторах вставлена строка, выводящая сообщение на консоль. Так можно отследить, какие конструкторы вызываются во время десериализации. Видно, что для объектов, порожденных от Serializable -классов, конструкторы не вызываются вовсе. Идет обращение лишь к конструктору без параметров не- Serializable -суперкласса.

Сравним значения полей первого объекта и его копии, полученной десериализацией. Поля, унаследованные от не- Serializable -класса ( firstName, lastName ), не восстановились. Они имеют значения, полученные в конструкторе Parent без параметров. Поля, объявленные в Serializable -классе, свои значения сохранили. Это верно и для второго объекта – собственные поля Child2 и унаследованные от Child имеют точно такие же значения, что и до сериализации. Их значения были записаны, а потом считаны и напрямую установлены из потока данных.

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

Воронцов. Перезагрузка. Книга 2

Тарасов Ник
2. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Воронцов. Перезагрузка. Книга 2

Алекс и Алекс

Афанасьев Семен
1. Алекс и Алекс
Фантастика:
боевая фантастика
6.83
рейтинг книги
Алекс и Алекс

Егерь. Системный зверолов

Скиба Николай
1. Зверолов
Фантастика:
рпг
уся
фэнтези
фантастика: прочее
попаданцы
6.50
рейтинг книги
Егерь. Системный зверолов

Жизнь, которой не было

Денис Палимов
1. Жизнь, которой не было
Фантастика:
городское фэнтези
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Жизнь, которой не было

Эрсус. Инферно

Павлов Вел
3. Стезя Эрсуса
Фантастика:
фэнтези
5.00
рейтинг книги
Эрсус. Инферно

Твое сердце будет разбито. Книга 1

Джейн Анна
Любовные романы:
современные любовные романы
6.00
рейтинг книги
Твое сердце будет разбито. Книга 1

Егерь. Прилив. Книга 10

Скиба Николай
10. Зверолов
Фантастика:
рпг
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Егерь. Прилив. Книга 10

Первый среди равных. Книга VIII

Бор Жорж
8. Первый среди Равных
Фантастика:
аниме
фантастика: прочее
эпическая фантастика
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга VIII

Переговоры

Форсайт Фредерик
Детективы:
политические детективы
5.75
рейтинг книги
Переговоры

Геном хищника. Книга четвертая

Гарцевич Евгений Александрович
4. Я - Легенда!
Фантастика:
боевая фантастика
рпг
попаданцы
5.00
рейтинг книги
Геном хищника. Книга четвертая

Ваше Сиятельство 3

Моури Эрли
3. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 3

Кодекс Охотника. Книга XXIX

Винокуров Юрий
29. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXIX

Медный страж

Прозоров Александр Дмитриевич
9. Ведун
Фантастика:
фэнтези
8.58
рейтинг книги
Медный страж

Личный враг

Кораблев Родион
26. Другая сторона
Фантастика:
боевая фантастика
рпг
фантастика: прочее
постапокалипсис
попаданцы
5.00
рейтинг книги
Личный враг