Читаем Философия Java3 полностью

Итак, объект BLip2 в программе не восстанавливается — попытка приводит к возникновению исключения. Заметили ли вы различие между классами Blipl и ВИр2? Конструктор класса Blipl объявлен открытым (public), в то время как конструктор класса Blip2 таковым не является, и именно это приводит к исключению в процессе восстановления. Попробуйте объявить конструктор класса Blip2 открытым и удалить комментарии //!, и вы увидите, что все работает, как и было запланировано.

При восстановлении объекта Ы вызывается конструктор по умолчанию класса Blipl. Это отличается от восстановления объекта, реализующего интерфейс Serializable, которое проводится на основе данных сериализации, без вызова конструкторов. В случае с объектом Externalizable происходит нормальный процесс конструирования (включая инициализацию в точке определения), и далее вызывается метод readExternal(). Вам следует иметь это в виду при реализации объектов Externalizable — в особенности обратите внимание на то, что вызывается конструктор по умолчанию.

Следующий пример показывает, что надо сделать для полноты операций сохранения и восстановления объекта Externalizable:

// io/Blip3 java

// Восстановление объекта Externalizable import java io *,

import static net.mindview util.Print *;

public class Blip3 implements Externalizable { private int i.

private String s; // Без инициализации public Blip3() {

print("Конструктор Blip3"). // s, i не инициализируются

}

public Blip3(String x. int a) {

print("Blip3(String x, int a)"), s = x, i = a.

// s и i инициализируются только вне конструктора по умолчанию

public String toStringO { return s + i; } public void writeExternal(ObjectOutput out) throws IOException {

print("Blip3.writeExternal"); // Необходимо действовать так: out.writeObject(s); out.writelntCi);

}

public void readExternal(Objectlnput in) throws IOException, ClassNotFoundException { pri nt("B1i p3.readExternal"); // Необходимо действовать так: s = (String)in.readObjectO; i = in.readlntO:

}

public static void main(String[] args) throws IOException, ClassNotFoundException { print("Создание объектов:"): Blip3 ЬЗ = new Blip3("Строка ", 47);

print(b3);

ObjectOutputStream о = new ObjectOutputStream(

new File0utputStream("Blip3 out")); print("Сохранение объекта:"); o.write0bject(b3); о.closeO: // Now get it back:

ObjectInputStream in = new ObjectInputStream(

new Fi1eInputStream("B1ip3.out")); print("Восстановление ЬЗ:"); ЬЗ = (Blip3)in. readObjectO; print(b3);

}

} /* Output: Создание объектов: Blip3(String x, int a) Строка 47

Сохранение объекта: Blip3.writeExternal Восстановление ЬЗ: Конструктор Blip3 B1i рЗ.readExternal Строка 47 *///:-

Поля s и i инициализируются только во втором конструкторе, но не в конструкторе по умолчанию. Это значит, что, если переменные s и i не будут инициализированы в методе readExternal(), s останется ссылкой null, a i будет равно нулю (так как при создании объекта его память обнуляется). Если вы закомментируете две строки после фраз Необходимо действовать так и запустите программу, то обнаружите, что так оно и будет: в восстановленном объекте ссылка s имеет значение null, а целое i равно нулю.

Если вы наследуете от объекта, реализующего интерфейс Externalizable, то при выполнении сериализации следует вызывать методы базового класса writeExternal() и readExternal(), чтобы правильно сохранить и восстановить свой объект.

Итак, чтобы сериализация выполнялась правильно, нужно не просто записать всю значимую информацию в методе writeExternal() (для объектов Externalizable не существует автоматической записи объектов-членов), но и восстановить ее затем в методе readExternal(). Хотя сначала можно запутаться и подумать, что из-за вызова конструктора по умолчанию все необходимые действия по записи и восстановлению объектов Externalizable происходят сами по себе. Но это не так.

Ключевое слово transient

При управлении процессом сериализации может возникнуть ситуация, при которой автоматическое сохранение и восстановление некоторого подобъекта нежелательно — например, если в объекте хранится некоторая конфиденциальная информация (пароль и т. д.). Даже если информация в объекте описана как закрытая (private), это не спасает ее от сериализации, после которой можно извлечь секретные данные из файла или из перехваченного сетевого пакета.

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

Однако работать с объектами Serializable удобнее, поскольку сериализация для них проходит полностью автоматически. Чтобы запретить запись некоторых полей объекта Serializable, воспользуйтесь ключевым словом transient. Фактически оно означает: «Это не нужно ни сохранять, ни восстанавливать — это мое дело».

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных