пятница, 4 февраля 2011 г.

Сериализация в Java

Несколько основных моментов насчет сериализации.
Простейший пример сериализации и десериализации объекта класса в файл:
import java.io.Serializable; 
class TestSerial implements Serializable {
private static final long serialVersionUID = 565645645688l;
private byte field1 = 100;
private String field2 = "field2";
public byte getField1() {
return field1;
}

public String getField2() {
return field2;
}
//Реализация алгоритма сериализации
public static void serialize() throws IOException {
FileOutputStream fos = new FileOutputStream("temp.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
TestSerial ts = new TestSerial();
oos.writeObject(ts);
oos.flush();
oos.close();
}

//Код, приведённый в методе serialize сериализует состояние экземпляра класса TestSerial 
//в файл temp.out. Для воссоздания объекта, нужно произвести 
//десериализацию, как показано в методе deserialize.

//Воссоздание сериализованного объекта
public static void deserialize() throws IOException {
FileInputStream fis = new FileInputStream("temp.out");
ObjectInputStream oin = new ObjectInputStream(fis);


TestSerial ts = (TestSerial) oin.readObject();
System.out.println("field1="+ts.getField1());
System.out.println("field2="+ts.getField2());
}
}

Модификаторы полей
 Существует такой модификатор поля как transient. Он означает, что это поле не должно быть сериализовано. При десериализации объекта класса такому полю присваивается значение null.
  При сериализации поля, имеющие модификатор static, не сериализуются. Соответственно, после десериализации это поле значения не меняет.
 Поля с модификатором final сериализуются как и обычные.

SerialVersionUID
 Еще один очень важный момент. При стандартной сериализации учитывается порядок объявления полей в классе. Потому, при изменении порядка десериализация пройдет не так как положено. Чтобы этого избежать, добавлен следующий механизм. В каждый класс, реализующий интерфейс Serializable, на стадии компиляции добавляется еще одно поле – private static final long serialVersionUID. Это поле содержит уникальный идентификатор версии сериализованного класса. Оно вычисляется по содержимому класса – полям, их порядку объявления, методам, их порядку объявления. Соответственно, при любом изменении в классе это поле поменяет свое значение, и при загрузке, если значение поля изменилось в текущем классе - будет выдана ошибка.
Есть, однако, способ эту проверку если обойти. Это может оказаться полезным, если набор полей класса и их порядок уже определен, а методы класса могут меняться. В этом случае сериализации ничего не угрожает, однако стандартный механизм не даст десериализовать данные с использованием байткода измененого класса. Но, как я уже сказал, его можно обмануть. А именно – вручную в классе определить поле private static final long serialVersionUID. Значение его для этого класса можно получить, использовав утилиту serialver, входящую в поставку SDK. После такого определения значение поля будет фиксировано, следовательно, десериализация всегда будет разрешена.
Более того, в версии 5.0 в документации появилось приблизительно следующее: крайне рекомендуется всем сериализуемым классам декларировать это поле в явном виде, ибо вычисление по умолчанию очень чувствительно к деталям структуры класса, которые могут различаться в зависимости от реализации компилятора, и вызывать таким образом неожиданные InvalidClassException при десериализации. Объявлять это поле лучше как private, т.к. оно относится исключительно к классу, в котором объявляется. Хотя в спецификации модификатор не оговорен.

Кроме сериализации путем имплементирования класса Serializable, существует ещё один более "продвинутый" способ сериализации - путем имплелементирования класса Externalizable.

Комментариев нет:

Отправить комментарий

Ярлыки

java (28) оптимизация (7) CPanel (5) svn (5) windows xp (5) ошибка (5) свой сервер (5) файлы и папки (5) gui (4) регулярные выражения (4) redmine (3) windows (3) автоматизация (3) защита данных (3) резервное копирование (3) сервер (3) JavaScript (2) Oracle SQL (2) adsl модем (2) apache tomcat (2) dropbox (2) excel (2) firewall (2) netbeans (2) office 2007 (2) samsung (2) system tray (системный трей) (2) xerox (2) вирусы (2) принтер (2) сериализация (2) удаленный рабочий стол (2) HTML (1) JFileChooser (1) MySQL (1) Nokia (1) Ovi (1) P660R-T1 (1) WakeOnLan (1) blogger.com (1) ctfmon.exe (1) email (1) flash память (1) ftp (1) ip (1) jQuery (1) jvisualWm (1) log4j (1) look and feel (1) myBatis (1) php (1) serialVersionUID (1) skype (1) smtp (1) ssh (1) swing (1) torrents (1) unix (1) vpn (1) windows 7 (1) xStarter (1) zip (1) безопасность (1) вход в систему (1) дизайн (1) документация (1) заправка (1) интернет (1) логирование (1) мышь (1) патч (1) перенос (1) печать (1) плагины (1) почтовые сообщения (1) программирование (1) процессы (1) прошивка (1) сеть (1) сеть. ошибка (1) скрытые файлы (1) списки (1) фильтрация (1) фокус (1) часовые пояса (1) шифрование (1) экран (1)