WebClub - Всероссийский Клуб Веб-разработчиков
WebClub.RU » Архив » Серийность и совместимость классов

Серийность и совместимость классов


Дата публикации: 17-03-2013

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

Java осуществляет сохранение состояния объекта очень просто. Этот процесс известен как "серийность" или "объектная инерция". Чтобы сделать объект постоянным, класс должен выполнить интерфейс java.lang.Serializable. Этот интерфейс не имеет методов; он только указывает, что класс, который делает это, может быть серийным. Следующая программа показывает это:

import java.io.*;

/** Demonstrates how to serialize an object. */
public class SerialVerDemo implements Serializable {

/** The data to be written to the stream. */
String data;
/** Temporary data. */
transient int temp;

/** Main. */
public static void main(String[] args) {

try {

SerialVerDemo svd = new SerialVerDemo();
svd.temp = 1;
svd.data = "Version 1";

// Serialize (write the object to a stream)
ObjectOutputStream out = new ObjectOutputStream(
new FileOutputStream("output.ser"));
out.writeObject(svd);
out.close();

// Deserialize (prepare an object from the stream)
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("output.ser"));
SerialVerDemo newSVD = (SerialVerDemo)in.readObject();
in.close();

// Display the details of the read in object
System.out.println("Read: Data = " + newSVD.data
+", Temp = " + newSVD.temp);

}
catch(Exception e) {
System.out.println("main(): Caught " + e.getMessage());
e.printStackTrace();
}

}

}
Метод main(), во первых, создает образец SerialVerDemo и инициализирует элемент data в "Version 1". Затем он преобразовывает объект в файл с именем "output.ser". Класс ObjectOutputStream поддерживает методы для записи объектов и примитивных типов данных (типа int) в выходной поток. Метод WriteObject() ожидает, что класс будет серийным. Это причина по которой SerialVerDemo выполняет интерфейс java.io.Serializable. Обратите внимание на использование ключевого слова transiaent в описании temp. Оно используется, чтобы избежать его серийности. Фактически, метод writeObject() записывает не transient и не static элементы.
Наконец, класс создает объект из файла и отображает объект ввода. Этот процесс построения объекта из потока известен как "де-серийность". Результат этой программы будет такой

Read: Data = Version 1, Temp = 0
Это было просто, не так ли? В этом красота Jav'ы. Java делает некоторые сложные задачи простыми. Далее будет еще интереснее.
В этом мире изменяющихся требований дизайн класса также часто меняется. Это могло бы иметь последствия в случае, когда вы управляете (де)серийностью. Например, если вы добавляете член newData к вышеупомянутому классу, то как сможет метод readObject() обеспечить значение для этого элемента, если объект создавался из старого серийного файла? Это привело бы к ошибке InvalidClassException, так как класс версии несовместим.

Java упрощает эту задачу, обеспечивая совместимость класса с более старой версией. Просто следуйте этим указаниям:
1. Найдите id серийной версии старого класса (перед модификацией) используя утилиту "serialver", которая поставляется с JDK и связывается следующим образом:
Serialver имя класса
Это даст вам полное объявление элемента, который вы должны использовать в вашем новом классе.
2. Добавьте элемент с вышеупомянутым объявлением в новую версию класса.

Далее показана модифицированная версия вышеупомянутой программы, которая является совместимой со старой версией.

import java.io.*;

/** Demonstrates how to make a class compatible with its previous version. */
public class SerialVerDemo implements Serializable {

/** For class compatibility. */
static final long serialVersionUID = -1400192891420044735L;

/** The data to be written to the stream. */
String data;
/** Temporary data. */
transient int temp;
/** The new field. */
String newData;

/** Main. */
public static void main(String[] args) {

try {

// Deserialize (prepare an object from the stream)
ObjectInputStream in = new ObjectInputStream(
new FileInputStream("output.ser"));
SerialVerDemo newSVD = (SerialVerDemo)in.readObject();
in.close();

// Display the details of the read in object
System.out.println("Read: Data = " + newSVD.data
+", Temp = " + newSVD.temp);

}
catch(Exception e) {
System.out.println("main(): Caught " + e.getMessage());
e.printStackTrace();
}

}

}
Обратите внимание на использование "serialVersionUID" для указания того, что текущий класс совместим с классом, имеющим эту id версию. Main() пытается читать "output.ser" файл, созданный старым классом в предыдущей программе. Так как класс версии совместим, readObject() возвращает сообщение об успешном выполнении.
Особенность, заслуживающая внимания здесь - это серийность, применение которой не ограничивается файлами. Вы можете использовать ее, чтобы передать объекты над любым потоком.
Домен продается

Популярное

Не так давно в сети появился новый сервис, под названием Dead Man Zero. Этот сервис сделал...
Рынок социальных площадок уже давно стал стабильным. Несмотря на то, что время от времени...
Artisteer 4 – единственный в своем роде продукт, позволяющий автоматизировать работу над созданием...
Апрель 2024 (1)
Октябрь 2018 (14)
Февраль 2017 (3)
Январь 2017 (1)
Август 2016 (1)
Май 2016 (2)

Карта сайта: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41

Друзья сайта



Случайная цитата

Alan Kay:

"Lisp — это не язык, а строительный материал."

Опрос

Какой антивирус Вы используете?

Kaspersky Antivirus
NOD32
Norton Antivirus
Dr.Web
Panda
Аvast!
ClamWin
Другой...