Управляемая сериализация в Java: Externalizable
Last updated: 7 мая 2025 г.Externalizable
– управляемая сериализация.
Представим, что нужно сериализовать объект созданного нами класса расширяющий вообще сторонний класс, который не Serializable, из вообще стороннего jar, который мы скачали откуда-то из интернета.
Ясное дело, поля стороннего класса не сериализуються и не десериализуються.
Externalizable поможет. Благодаря нему можно силой сериализовать и десериализовать поля стороннего класса реализовав методы writeExternal
(для сер) и readExternal
(для дес).
Пример программы:
1import java.io.*;
2
3public class ExternalizableExample {
4 public static void main(String[] args) {
5 // сериализуем
6 try(ObjectOutputStream oos =
7 new ObjectOutputStream(
8 new FileOutputStream("person.dat")))
9 {
10 Person p = new Person("Sam", 33, 178, true, 118);
11 oos.writeObject(p);
12 }
13 catch(Exception ex){
14 System.out.println(ex.getMessage());
15 }
16 // десериализация
17 try(ObjectInputStream ois =
18 new ObjectInputStream(
19 new FileInputStream("person.dat")))
20 {
21 Person p = (Person) ois.readObject();
22 System.out.printf(
23 "Name: %s \\t Age: %d \\t Height: %d \\t " +
24 "Married: %b \\t IQ: %d \\n",
25 p.getName(), p.getAge(), p.getHeight(),
26 p.getMarried(), p.getIQ());
27 }
28 catch(Exception ex){
29 System.out.println(ex.getMessage());
30 }
31 }
32}
33
34// представим что типа сторонний класс,
35// который не реализует Serializable
36// и нет никакой возможности
37// сделать его Serializable
38// но сериализовать его надо
39class MyClass {
40
41 private boolean married;
42 private int IQ;
43 public MyClass() {}
44 public MyClass(boolean m, int iq) {
45 married = m; IQ = iq;
46 }
47
48 boolean getMarried() { return married; }
49 void setMarried(boolean married) {
50 this.married = married;
51 }
52 int getIQ() { return IQ; }
53 void setIQ(int IQ) { this.IQ = IQ; }
54}
55
56//вместо Serializable – Externalizable
57class Person extends MyClass
58 implements Externalizable{
59
60 private String name;
61 private int age;
62 private double height;
63 public Person(){}
64 public Person(String n, int a, double h,
65 boolean m, int iq) {
66 super(m, iq);
67 name=n; age=a; height=h;
68 }
69 String getName() {return name;}
70 void setName(String name) {this.name = name;}
71 int getAge() {return age;}
72 void setAge(int age){this.age = age;}
73 double getHeight(){return height;}
74 void setHeight(double height){this.height=height;}
75 @Override
76 public void writeExternal(ObjectOutput out)
77 throws IOException {
78 //вручную передаем методом сериализации
79 //(методам writeUTF, writeInt, …)
80 //поля сериализуемого объекта, которые
81 //мы хотим сериализовать
82 out.writeUTF(getName());
83 out.writeInt(getAge());
84 out.writeDouble(getHeight());
85 //это поле из класса, который не Serializable
86 out.writeBoolean(getMarried());
87 //и это поле из класса, который не Serializable
88 out.writeInt(getIQ());
89 //Но теперь мы можем такие
90 //поля сериализовать
91 //вот так вручную так сказать.
92 //Правда вручную теперь также нужно
93 //сериализовать и поля класса Person,
94 //который должен был быть Serializable,
95 //но он Externalizable по понятным причинам.
96 }
97 @Override
98 public void readExternal(ObjectInput in)
99 throws IOException, ClassNotFoundException {
100 //здесь учитывая порядок предшествующей
101 //сериализации полей в методе выше
102 //десериализуем их методами десериализации
103 setName(in.readUTF());
104 setAge(in.readInt());
105 setHeight(in.readDouble());
106 setMarried(in.readBoolean());
107 setIQ(in.readInt());
108 }
109}
Вывод:

Как видим, сериализуются все поля даже класса, который не Serializable.
Следующие уроки
Базы данных: основные принципы
13
мин.
Связь Один-ко-Многим в базах данных
14
мин.
Связь Многие-ко-Многим в базах данных
16
мин.