Bits of Java (トップ)

目次  前へ  次へ

フィールド serialPersistentFields を使った直列化フィールドの指定

transient キーワードは直列化不可のフィールドを指定しましたが static フィールド serialPersistentFields を使って直列化の対象となるフィールドを設定できます。 設定する直列化対象フィールドはこの serialPersistentFields を宣言しているクラスのフィールドのみでスーパークラスのフィールドを設定した場合は直列化の際に例外が発生します。 宣言は( private static final の順番を別にすると)正確に以下のようになります。

private static final ObjectStreamField[] serialPersistentFields
フィールド名は serialPersistentFields でなければなりません。 当たり前ですがスペルミスがあってもコンパイラはチェックしてくれませんので注意が必要です。 ObjectStreamField のコンストラクタは次の2つです。
public ObjectStreamField(String name, Class type)
public ObjectStreamField(String name, Class type, boolean unshared)
引数は最初がフィールド名で次がそのフィールドの Class オブジェクトで、 boolean 型の引数はこれに true を指定すると複数の変数により参照を保持されているオブジェクトでも復元時にはそれぞれ新たにオブジェクトが生成され参照の同一性は失われます。 false を指定した場合は引数の2つのコンストラクタと同じ動作になり、直列化の時に同じオブジェクトを参照していた変数には復元後にも復元時に作成された同じオブジェクトを参照します。 プリミティブ型の場合は以下のように作成します。
new ObjectStreamField("value", int.class)
new ObjectStreamField("flag", boolean.class)

BookSerializeSample の実行結果は以下です。

Book title:きまぐれロボット  author:星新一  object:null
transient を使った場合と同じで復元後のオブジェクトには直列化時の object のデータが失われています。このように直列化を行わなかったフィールドは数値型なら 0 に boolean 型なら false に参照型なら null になります。

/**************************** Book.java ****************************/
import java.io.ObjectStreamField;

public class Book implements java.io.Serializable {

    private static final ObjectStreamField[] serialPersistentFields = {
        new ObjectStreamField("title", String.class),
        new ObjectStreamField("author", String.class)
    };

    protected String title;
    protected String author;
    protected Object object = new Object();

    public Book() {}

    public Book(String title, String author) {
        this.title  = title;
        this.author = author;
    }
//--------------------------------------------------------------------
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
//--------------------------------------------------------------------
    public String toString() {
        return "Book title:" + title + "  author:" + author +
               "  object:" + object;
    }
}



/********************* BookSerializeSample.java *********************/
import java.io.*;

public class BookSerializeSample {
    public static void main(String[] args) throws Exception {
        Book book = new Book("きまぐれロボット", "星新一");
        ObjectOutputStream out = null;
        ObjectInputStream in = null;
        try {
            out = new ObjectOutputStream(
                      new BufferedOutputStream(
                          new FileOutputStream("bookdata")));
            out.writeObject(book);
            out.close();
            out = null;

            in = new ObjectInputStream(
                     new BufferedInputStream(
                         new FileInputStream("bookdata")));
            System.out.println(in.readObject());

        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {}
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {}
            }
        }
    }
}