入門シリアライズ
環境
- JDK 21
シリアライズって何?
一言で言うと「インスタンスをファイル化する技術」です。インスタンスをファイル化することを シリアライズ 、ファイルからインスタンスに戻すことを デシリアライズ と言います。
シリアライズを利用することで、次のようなことが可能になります。
- インスタンスを一時保存して、後でまた使う
- ファイルを転送して、他の場所でインスタンスを使う
シリアライズは、われわれ開発者が使うことはほぼありません。次で説明するように、アプリケーションんサーバーなどがわれわれの見えないところで行なっていることがほとんどです。しかし、見えないところで何が起こっているかを知ることは重要です。なので1回は自分でもシリアライズのコードを書いてみることをお勧めします。
シリアライズとHttpSession
特に業務でよく出てくるのはHttpSession
に保存する値です。Tomcatなどのアプリケーションサーバーは、HttpSession
にsetAttribute()
で保存された値をシリアライズすることがあります。
HttpSession
とは何ぞや、については下記の資料をご確認ください。
Webアプリケーションセキュリティの基礎とSpring Bootでの実装
これによって、次のようなことが可能になります。
- アプリケーションサーバーが一時停止時に、
HttpSession
に保存されていた値をシリアライズしてファイルとして保存する。すると再起動時にデシリアライズすることで、HttpSession
に保存されていた値を再び利用可能になる
- アプリケーションサーバーがクラスター構成(複数台構成)になっている際、
HttpSession
に保存されていた値をシリアライズして、そのファイルをクラスター内の別サーバーに転送する。これによりクラスター内の全サーバーで同じ値がHttpSession
に保存される
Serializableインタフェース
すべてのインスタンスがシリアライズ可能なわけではありません。 java.io.Serializable
インタフェース を実装したクラスのインスタンスのみ、シリアライズ可能です。
今回はこのインタフェースを実装して、次のようなクラスを作成します。
package com.example;
import java.io.Serializable;
public record Person(String name, int age) implements Serializable {
}
もし、このインタフェースを実装していないクラスのインスタンスをシリアライズしようとすると、java.io.NotSerializableException
がスローされます。
Exception in thread "main" java.io.NotSerializableException: com.example.Person
at java.base/java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1200)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:358)
at com.example.SerializationMain.main(SerializationMain.java:13)
シリアライズしてみる
シリアライズは ObjectOutputStream#writeObject()
メソッド で行います。
package com.example;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializationMain {
public static void main(String[] args) throws Exception {
Person person = new Person("Alice", 30);
try (
FileOutputStream fos = new FileOutputStream("person.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos)
) {
oos.writeObject(person);
System.out.println("シリアライズが正常に完了しました。");
}
}
}
これを実行すると、カレントフォルダにperson.serというファイルが作成されます(ファイル名やファイルの拡張子には特に制限はありません)。これがシリアライズされたPerson
インスタンスです。
デシリアライズしてみる
デシリアライズは ObjectInputStream#readObject()
メソッド で行います。
package com.example;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeserializationMain {
public static void main(String[] args) throws Exception {
try (
FileInputStream fis = new FileInputStream("person.ser");
ObjectInputStream ois = new ObjectInputStream(fis)
) {
Person person = (Person) ois.readObject();
System.out.println("デシリアライズされたPersonインスタンス: " + person);
}
}
}
デシリアライズされたPersonインスタンス: Person[name=Alice, age=30]
Discussion