Бесплатный курс по Java: от основ до продвинутого уровня
Управляемая сериализация в Java: Externalizable
Externalizable – управляемая сериализация.
Представим, что нужно сериализовать объект созданного нами класса расширяющий вообще сторонний класс, который не Serializable, из вообще стороннего jar, который мы скачали откуда-то из интернета.
Ясное дело, поля стороннего класса не сериализуються и не десериализуються.
Externalizable поможет. Благодаря нему можно силой сериализовать и десериализовать поля стороннего класса реализовав методы writeExternal (для сер) и readExternal (для дес).
Пример программы:
import java.io.*;
public class ExternalizableExample {
public static void main(String[] args) {
// сериализуем
try(ObjectOutputStream oos =
new ObjectOutputStream(
new FileOutputStream(“person.dat”)))
{
Person p = new Person(“Sam”, 33, 178, true, 118);
oos.writeObject(p);
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
// десериализация
try(ObjectInputStream ois =
new ObjectInputStream(
new FileInputStream(“person.dat”)))
{
Person p = (Person) ois.readObject();
System.out.printf(
“Name: %s \\t Age: %d \\t Height: %d \\t ” +
“Married: %b \\t IQ: %d \\n”,
p.getName(), p.getAge(), p.getHeight(),
p.getMarried(), p.getIQ());
}
catch(Exception ex){
System.out.println(ex.getMessage());
}
}
}
// представим что типа сторонний класс,
// который не реализует Serializable
// и нет никакой возможности
// сделать его Serializable
// но сериализовать его надо
class MyClass {
private boolean married;
private int IQ;
public MyClass() {}
public MyClass(boolean m, int iq) {
married = m; IQ = iq;
}
boolean getMarried() { return married; }
void setMarried(boolean married) {
this.married = married;
}
int getIQ() { return IQ; }
void setIQ(int IQ) { this.IQ = IQ; }
}
//вместо Serializable – Externalizable
class Person extends MyClass
implements Externalizable{
private String name;
private int age;
private double height;
public Person(){}
public Person(String n, int a, double h,
boolean m, int iq) {
super(m, iq);
name=n; age=a; height=h;
}
String getName() {return name;}
void setName(String name) {this.name = name;}
int getAge() {return age;}
void setAge(int age){this.age = age;}
double getHeight(){return height;}
void setHeight(double height){this.height=height;}
@Override
public void writeExternal(ObjectOutput out)
throws IOException {
//вручную передаем методом сериализации
//(методам writeUTF, writeInt, …)
//поля сериализуемого объекта, которые
//мы хотим сериализовать
out.writeUTF(getName());
out.writeInt(getAge());
out.writeDouble(getHeight());
//это поле из класса, который не Serializable
out.writeBoolean(getMarried());
//и это поле из класса, который не Serializable
out.writeInt(getIQ());
//Но теперь мы можем такие
//поля сериализовать
//вот так вручную так сказать.
//Правда вручную теперь также нужно
//сериализовать и поля класса Person,
//который должен был быть Serializable,
//но он Externalizable по понятным причинам.
}
@Override
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
//здесь учитывая порядок предшествующей
//сериализации полей в методе выше
//десериализуем их методами десериализации
setName(in.readUTF());
setAge(in.readInt());
setHeight(in.readDouble());
setMarried(in.readBoolean());
setIQ(in.readInt());
}
}
Вывод:
Как видим, сериализуются все поля даже класса, который не Serializable.