オブジェクト・シリアライゼイション
オブジェクトの状態を保存することを「オブジェクト・シリアライゼイション」と言います。 簡単なデータを保存するのであれば、単なるテキストファイルに文字列として書き出せばいいのですが、 複雑なオブジェクトを保存したいときには、オブジェクトをシリアライズして保存した方が便利です。 また、ネットワークプログラミングなどで、他のクライアントに自分の状態を知らせたりするときにも 有効でしょう。

ここでは、人を表すManクラスを使って、オブジェクト・シリアライゼイションのテストをします。 Manクラスは名前とIDを持つシンプルなクラスです。はじめに「太郎」という名前のManオブジェクトを 生成して、ファイルにシリアライズして保存します。そのあとで、新たなManクラス型のwhoに 先ほどのファイルからオブジェクトを復元して代入します。このwhoの情報を見ると どうなっているでしょうか?

以下がソースです。

			
import java.io.*;

public class ObjectSerializationTest {
    public final static String FILE_NAME = "data.txt"; //データを保存するファイル名
	
    public static void main(String[] args) {
        Man taro = new Man("太郎", 4296);  //太郎を作成
		
        /*オブジェクトをシリアライズ*/
        try {
            FileOutputStream fos = new FileOutputStream(FILE_NAME);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(taro);
        } catch(Exception e) {}
		
        Man who = null;   //誰?
		
        /*オブジェクトを復元*/
        try {
            FileInputStream fis = new FileInputStream(FILE_NAME);
            ObjectInputStream ois = new ObjectInputStream(fis);
            who = (Man)ois.readObject();
        } catch(Exception e) {}
		
        System.out.println(who.getState()); //誰かの情報を得る
    }
}

/*人を表すクラス*/
class Man implements Serializable {
    private String name;   //名前
    private int id;        //ID
	
    Man(String name, int id) {
        this.name = name;
        this.id = id;
    }
	
    /*このオブジェクトの情報を返す*/
    public String getState() {
        return name + "/" + id;
    }
}

注意すべき点は、シリアライズするクラスにはSerializableインタフェースを実装させなければ ならない点です。このSerializableインタフェースのコードは以下のようになっています。

			
/*Serializable.java*/
public interface Serializable {
}

見れば分かるように空です。何故こんなインタフェースを実装させる必要があるのでしょうか?

この空のインタフェースは、クラスに印を付ける役割を持ちます。空のインタフェースを使ってクラスを 分類すると、例えばそのクラスがある例外を投げる可能性を示唆できます。それによって、 instanceof演算子を使って場合分けを行い、必要なクラス(そのインタフェースを実装しているクラス) に対してだけtry-catch文を適用することが出来ます。発生するはずもない例外をtry-catch文で 囲むのは好ましくありません。他にも、Serializableインタフェースと似たような空のインタフェースに java.rmi.Remoteインタフェースや、java.lang.Cloneableインタフェースがあります。 これらのインタフェースも上記のような理由から存在します。 このように、印を付ける目的で作られたインタフェースを「マーカーインタフェース」と呼びます。

ちなみに、Serializableインタフェースを実装したクラスに、シリアライズさせたくないフィールドが ある場合には、そのフィールドをtransientとして宣言します。transientとは「一時的な」という意味で、 その名の通り、シリアライズする必要のない一時的な変数などに対して適用します。
実行結果