Java オブジェクトのシリアライズとデシリアライズ
Java オブジェクトのシリアライズとは?
ObjectInputStream と ObjectOutputStream を用いることによって、 Java オブジェクトをファイルに出力したり、ファイルからオブジェクトを元にもどしたりできます。
ハードディスクなどの記憶装置などにメモリ上のオブジェクトを記録することを永続化 (パーシスタント) といいますが、このときオブジェクトを記憶装置上のバイト列に表現することをシリアライズ (Serialize) といい、 記憶装置からデータを読み込んで Java オブジェクトに復元することをデシリアライズといいます。
ちなみに RPC とかの話などでリモートマシン上(あるいは何らかのバウンダリを越えた場所)にデータを送るような話をするときはマーシャリングといいます。
シリアライズ/デシリアライズ可能なオブジェクト
このページでは Company と Employee というクラスを作成し、それらのオブジェクトをシリアライズ、デシリアライズしてみましょう。
まず Company クラスは次のように定義します。
package com.keicode.java.test;
import java.io.Serializable;
public class Company implements Serializable {
String name;
int numberOfEmployee;
public Company(String name, int numberOfEmployee) {
this.name = name;
this.numberOfEmployee = numberOfEmployee;
}
public String getName() {
return name;
}
public int getNumberOfEmployee() {
return numberOfEmployee;
}
}
次に Employee クラスは次の通りとします。
package com.keicode.java.test;
import java.io.Serializable;
public class Employee implements Serializable {
String name;
String email;
public Employee(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
ここでのポイントは、 Serializable インターフェイスを実装していることです。
実装していると言っても、Serializable インターフェイスはメソッドを持たない単なるマーカー・インターフェイスですから、 特に実装が必要なメソッドはありません。
ObjectOutputStream を用いた Java オブジェクトのシリアライズ
Java オブジェクトをファイルにシリアライズするには ObjectOutputStream を使います。 writeObject() メソッドにオブジェクトを渡します。
package com.keicode.java.test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class TestApp {
public static void main(String[] args) {
try {
ObjectOutputStream objOutStream =
new ObjectOutputStream(
new FileOutputStream("/Users/user1/obj.bin"));
Company company = new Company("Ace Inc.", 30);
Employee emp = new Employee("John Doe", "johnd@example.com");
objOutStream.writeObject(company);
objOutStream.writeObject(emp);
objOutStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ここでは Company オブジェクト、Employee オブジェクトを順番にシリアライズしました。 このためデシリアライズするときも、この順番で読み込めばオブジェクトが元に戻ります。
ObjectInputStream を用いた Java オブジェクトのデシリアライズ
Company オブジェクト、Employee オブジェクトをファイルから読み込んで元にもどしてみましょう。つまりデシリアライズしてみましょう。
package com.keicode.java.test;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class TestApp {
public static void main(String[] args) {
try {
ObjectInputStream objInStream
= new ObjectInputStream(
new FileInputStream("/Users/user1/obj.bin"));
Company company = (Company) objInStream.readObject();
Employee emp = (Employee) objInStream.readObject();
objInStream.close();
// 結果を出力
System.out.println(company.getName() + " - "
+ company.getNumberOfEmployee());
System.out.println(emp.getName() + " - " + emp.getEmail());
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
シリアライズするときに、Company、Employee の順番だったので、読み込むときも同じ順番で読み込んでいます。
Ace Inc. - 30
John Doe - johnd@example.com
確かにこのように元に戻せたことが確認できました。