- •Ввод-вывод. Сериализация
- •Цели занятия
- •Ввод-вывод
- •Ввод-вывод
- •Ввод-вывод
- •Ввод-вывод
- •Ввод-вывод
- •Байтовые потоки
- •InputStream
- •InputStream
- •InputStream
- •InputStream
- •InputStream
- •InputStream
- •OutputStream
- •OutputStream
- •OutputStream
- •Символьные потоки
- •Reader
- •Reader
- •Reader
- •Различия Reader и InputStream
- •Reader
- •Writer
- •Writer
- •Writer
- •Символьные и стандартные потоки
- •InputStreamReader и
- •InputStreamReader и
- •InputStreamReader и
- •Краткий обзор классов потоков
- •Потоки Filter
- •Потоки Buffered
- •Потоки Buffered
- •Потоки Buffered
- •Потоки Piped
- •Потоки Piped
- •Потоки Piped
- •Байтовые потоки ByteArray
- •Символьные потоки CharArray и
- •Потоки Print
- •Потоки Print
- •Класс StreamTokenizer
- •Класс StreamTokenizer
- •Класс StreamTokenizer
- •Класс StreamTokenizer
- •Байтовые потоки Data. DataInput и
- •Классы потоков Data
- •Классы потоков Data
- •Классы потоков Data
- •Класс File
- •Потоки File
- •Потоки File
- •Сериализация объектов
- •Сериализация объектов
- •Сериализация объектов
- •Подготовка классов к
- •Подготовка классов к
- •Подготовка классов к
- •Порядок сериализации и
- •Порядок сериализации и
- •Порядок сериализации и
- •Порядок сериализации и
- •Порядок сериализации и
- •Порядок сериализации и
- •Настройка механизма
- •Настройка механизма
- •Настройка механизма
- •Настройка механизма
- •Контроль версий объектов
- •Контроль версий объектов
- •Контроль версий объектов
- •Контроль версий объектов
- •Литература
Настройка механизма
сериализации
71• Подобные переопределённые варианты методов writeObject() и readObject() вызываются только в контексте объектов соответствующих классов, и методы несут ответственность исключительно за состояние объекта класса как такового, в том числе и в части, унаследованной от базового класса, не поддерживающего механизм сериализации
•Если в составе класса реализованы собственные варианты методов writeObject() и readObject(), они не должны обращаться к одноимённым методам базового класса
private void writeObject(ObjectOutputStream out) throws IOException
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Настройка механизма
сериализации
72• В объявлении метода writeObject() обозначена вероятность выбрасывания им исключения типа
IOException, так как оно может быть сгенерировано любым из «низкоуровневых» методов write(), которые будут здесь вызываться, и если подобное произойдёт, процесс сериализации должен быть завершён аварийным образом
•В предложении throws объявления метода readObject() также следует упомянуть исключение IOException – оно может быть выброшено вызываемыми методами read(), а в такой ситуации процесс десериализации следует остановить
•Помимо того, метод readObject() способен генерировать и исключение типа ClassNotFoundException, так как в общем случае при десериализации полей текущего объекта может потребоваться загрузка и других классов
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Настройка механизма
сериализации
73• Существует ограничение, которое следует принять во внимание, приступая к настройке
механизма сериализации: нельзя присваивать значение полю final в теле метода readObject(), поскольку поля final могут быть проинициализированы только в блоках инициализации или конструкторах
•Механизм сериализации, предусмотренный по умолчанию, однако, способен «обходить» это ограничение – он вполне нормально работает и с теми классами, в составе которых имеются поля final
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Контроль версий объектов
74 • Реализация классов со временем изменяется
•Если подобное происходит в промежутке времени между сериализацией и десериализацией объекта этого класса, поток ObjectInputStream способен обнаружить факт внесения изменений
•При сохранении объекта вместе с ним записывается уникальный идентификатор номера версии – 64-битовое значение типа long
•По умолчанию идентификатор создаётся в виде хеш-кода, построенного на основе информации об именах класса, его членов и базовых интерфейсов
•Изменение таких данных служит сигналом о возможной несовместимости версий класса
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Контроль версий объектов
75• При вводе данных об объекте из потока ObjectInputStream считывается также и идентификатор
номера версии
•Затем предпринимается попытка загрузки соответствующего класса
•Если требуемый класс не найден, либо идентификатор загруженного класса не совпадает с тем, который считан из потока, метод readObject() выбрасывает исключение типа InvalidClassException
•Если успешно загружены все нужные классы и выявлено совпадение всех идентификаторов, объект, как принято считать, может быть подвергнут десериализации
•Таким образом, получается, что любое, даже самое незначитнельное, изменение в структуре класса способно привести к несовместимости версий
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Контроль версий объектов
76• Но во многих случаях модификация классов носит отнюдь не радикальный характер
•Существует возможность сохранить совместимость класса, снабжённого дополнительными несущественными нововведениями, с данными ранее сериализованных объектов
•Для этого следует принудительно объявить в составе класса специальное поле, содержащее значение идентификатора номера версии, например:
private static final long serialVersionUID = ...;
•Конкретное значение идентификатора рассчитывается средствами используемой среды разработки Java
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Контроль версий объектов
77 • Ничто не мешает использовать в качестве идентификатора и любое произвольное значение, если оно фиксируется в самой первой версии класса, но это не самое лучшее решение, так как вы почти наверняка не сможете столь же тщательно сгенерировать идентификатор, как это делают стандартные инструменты и обеспечить его уникальность, чтобы предотвратить возможные конфликты с хеш-кодами других классов
•Теперь, когда поток ObjectInputStream находит описание требуемого класса и сопоставляет его идентификатор с тем, который сохранён вместе с сериализованными данными, проблема несовместимости не возникнет, даже если реализация класса на самом деле подверглась изменению
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
Литература
78• Арнольд Кен, Гослинг Джеймс, Холмс Дэвид. Язык программирования Java. 3-е изд.: Пер. с
англ. – М.: Издательский дом «Вильямс», 2001. –
624 с.: ил. ISBN 5-8459-0215-0 (рус.).
•Хорстманн Кей С., Корнелл Гари. Java`2. Библиотека профессионала, том 1. Основы. 8-е издание.: Пер. с англ. – М.: ООО «И.Д. Вильямс», 2008. – 816 с.: ил. ISBN 978-5-8459-1378-4 (рус.).
Все права защищены. www.haulmont.ru info@haulmont.com |
© HAULMONT, 2013 |
