目次 | 前の項目 | 次の項目 Java オブジェクト直列化仕様


A.6 非共有の直列化復元されたオブジェクトの保護

クラスが、private または package private のオブジェクト参照フィールドを保持し、かつそのクラスが、クラス (またはパッケージ) の外部でこれらのオブジェクト参照を利用できないという事実次第で、参照されるオブジェクトを、直列化復元プロセスの一部として自己防衛的にコピーする必要があります。つまり、ストリームから直列化復元されるサブオブジェクトを、「信頼されない入力」として扱う必要があります。新たに作成したオブジェクトを初期化して、直列化復元されたサブオブジェクトと同じ値を保持させ、readObject メソッドを使ってサブオブジェクトの代替とする必要があります。たとえば、オブジェクトが private バイト配列フィールド b を保持する場合、次に示すように、このフィールドを private のままにしなければなりません。

    private void readObject(ObjectInputStream s)
        throws IOException, ClassNotFoundException
    {
        s.defaultReadObject();

        b = (byte[])b.clone();

        if (<invariants are not satisfied>)
            throw new java.io.StreamCorruptedException();
    }
この問題は、可変サブオブジェクトへの内部参照を含む不変オブジェクトの直列化を考慮する際に特に重要です。コンテナオブジェクトの直列化復元時に、サブオブジェクトをコピーするための特別な措置が何もとられない場合、直列化ストリームへの書き込み権限を持つ悪意のある第三者が、可変サブオブジェクトへの参照を偽造し、これらの参照を使ってコンテナオブジェクトの内部状態を変更することで、コンテナオブジェクトの不変性を侵害する場合があります。このような場合に備えて、不変のコンテナクラスがクラス固有の直列化復元メソッドを提供することがポイントです。直列化復元される各可変コンポーネントオブジェクトのプライベートなコピーの作成は、このメソッドを使って行います。不変性を維持するために、不変コンポーネントオブジェクトのコピーを作成する必要はないことに留意してください。

また、clone の呼び出しが、常にサブオブジェクトを自己防衛的にコピーする正しい方法とは限らないことに留意することも重要です。独立したコピーを作成するため (およびコピーへの参照を「横取り」しないため) に clone メソッドをあてにできない場合、別の方法でコピーを作成する必要があります。サブオブジェクトのクラスが final ではない場合、呼び出される clone メソッドやヘルパーメソッドがサブクラスによってオーバーライドされる可能性があるため、常に別の方法でコピーを作成する必要があります。



目次 | 前の項目 | 次の項目
Copyright © 1997-1999 Sun Microsystems, Inc. All Rights Reserved.