Bits of Java (トップ)

目次  前へ  次へ

writeReplace メソッドの実装

readResolove メソッドは復元時に復元されたオブジェクトの状態の変更やオブジェクトそのものの置き換えを可能にしましたが Serializable あるいは Externalizable インターフェイスを実装しているクラスに writeReplace メソッドを定義すると直列化されるオブジェクトの状態の変更やオブジェクトの置き換えが可能です。 直列化の前に直列化されるオブジェクトの writeReplace メソッドが実行されその戻り値が最終的に直列化されるオブジェクトとなります。 writeReplace メソッドでは自分のフィールドを変更してから自分の参照を返したり 自分と同じ型のオブジェクトを新たに作成して返したりすることが可能です。

writeReplace メソッドは Java の直列化フレームワークにおいて Serializable あるいは Externalizable インターフェイスを実装しているクラスが定義している場合に意味のあるメソッドであり、インターフェイスやどこかのクラスに定義されているメソッドをオーバーライドしているわけではありません。 writeReplace メソッドの定義はアクセス修飾子は任意で以下のようになります。

ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
readResolve メソッドと同様に直列化するクラスに定義されている場合のみ呼び出されます。 直列化の際にスーパークラスに定義された writeReplace メソッドが呼び出されることはありません。

下のプログラムは writeReplace メソッドの実装例ですが良い例が浮かばず処理内容が意味のないものになってしまいました。 どの Book オブジェクトを直列化する場合にも title が "foo" に author が "hoge" に書き換えられてから直列化されます。
BookSerializeSampleの実行結果は以下です。

Book title:foo  author:hoge
下の2つ実装は下の方が新たに Book オブジェクトを作成していますが結果的に復元されるオブジェクトは同じものになります。
    private Object writeReplace() throws ObjectStreamException {
        title = "foo";
        author = "hoge";
        return this;
    }
    private Object writeReplace() throws ObjectStreamException {
        return new Book("foo", "hoge");
    }

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

public class Book implements java.io.Serializable {
    protected String title;
    protected String author;

    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;
    }
//--------------------------------------------------------------------
    private Object writeReplace() throws ObjectStreamException {
        title = "foo";
        author = "hoge";
        return this;
    }
//--------------------------------------------------------------------
    public String toString() {
        return "Book title:" + title + "  author:" + author;
    }
}


/********************* 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) {}
            }
        }
    }
}