[目次] [前項目] [次項目]

直列化可能オブジェクトのバージョン化


トピック:

概要

Java オブジェクトが、直列化を使って状態をファイルに保管したり、塊としてデータベースに保管したりする場合、そのデータを読み込むクラスのバージョンがそのデータを書き込んだバージョンと異なる可能性があります。

バージョン化には、クラスの同一性に関し、いくつかの根本的な問題があります。たとえば、互換性のある変更とは何か、という問題があります。互換性のある変更とは、クラスとその呼び出し元との間の約束ごとに影響を与えない変更です。

このセクションでは、目標、前提条件、そして解決策について記述します。この解決策は、変更できるものを制限し、メカニズムを慎重に選択することによって、この問題に対処しようとするものです。

ここで示す解決策では、フィールドの追加やクラスの追加によって発展するクラスを「自動的に」処理するメカニズムを示します。直列化では、バージョン化は、バージョンごとにクラス固有のメソッドを実装することなく行われます。ストリーム形式は、クラス固有のメソッドを呼び出すことなく処理(トラバース)されます。

目標

目標は次のとおりです。

前提条件

前提条件は次のとおりです。

ストリームのバージョン化はだれが行うか

クラスの展開において、非展開クラスによって設定された約束ごとを維持するのは、展開された(後のバージョンの)クラスの責任です。これは、2 つの形をとります。まず、展開されたクラスは、元のバージョンによって与えられたインタフェースに関する既存の前提条件を壊すことはできません。それによって、展開されたクラスを元のクラスの代わりに使用することができます。次に、元の(または前の)バージョンと通信するとき、展開されたクラスは、以前のバージョンが非展開クラスの約束を引き続き満たせるだけの、十分で同等な情報を与えなければなりません。

ここで説明した目的のために、各クラスは、そのスーパー型によって定義されたインタフェースまたは約束を実装し、拡張します。クラスの新しいバージョン、たとえば、foo'は、fooのための約束を引き続き満足しなければなりませし、インタフェースを拡張したり、その実装を修正したりすることができます。

直列化を介したオブジェクト間の通信は、それらのインタフェースによって定義される約束には含まれていません。直列化は、実装間の私的なプロトコルです。各実装がそのクライアントによって期待される約束を満たせるように十分通信することは、その実装の責任です。

互換性のある Javaの型展開

Java言語仕様 の第 13 章に、Java クラスが展開するときのこれらのバイナリ互換の説明があります。バイナリ互換の柔軟性のほとんどは、クラス、インタフェース、フィールド、メソッドなどの名前の記号参照を、遅い段階でバインドすることに起因しています。

直列化されたオブジェクトストリームのバージョン化に対する設計の基本的な点を、下に示します。

直列化に影響する型変更

この概念を使えば、展開するクラスのいろいろなケースに対し、設計上どのように対応するかを説明することができます。これらのケースは、クラスのいずれかのバージョンによって書き込まれたストリームの観点から記述されます。ストリームが同じクラスの同じバージョンで読み込まれた場合、情報や機能が失われることはありません。このストリームは、元のクラスに関する唯一の情報源です。そのクラス記述は、それが元のクラス記述のサブセットである限り、そのストリームのデータと、再構成されるクラスのバージョンを一致させるのに十分な情報です。

これらの記述は、クラスの以前のバージョンか以後のバージョンを再構成するためにストリームを読み込む、という観点からのものです。RPC システムの用語でいえば、これは「受取り側が正しくする」システムです。書き込み側は、そのデータを最も適した形式で書き込みますので、受取り側は、その情報を解釈して必要な部分を抽出し、入手できない部分を補う必要があります。

互換性のない変更

クラスに対する互換性のない変更とは、相互運用性の保証が維持できないような変更です。クラスの展開の過程で起こる互換性のない変更には、次のものがあります。

互換性のある変更

クラスへの互換性のある変更は次のように処理されます。



[目次] [前項目] [次項目]

Copyright (C) 1996, 1997 Sun Microsystems, Inc. All rights reserved.