機械翻訳について

Javaオブジェクト直列化仕様: 5 - 直列化可能オブジェクトのバージョン管理


5.1 概要

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

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

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

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

5.2 目標

目標は次のとおりです。

5.3 前提

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

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

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

展開クラスと非展開クラスおよびそれらのインスタンス間でスーパー・タイプ関係を持つprivateな直列化プロトコルと規約
進化したクラスとそれ以外のクラスとそのインスタンス間のスーパータイプの関係を持つプライベート直列化プロトコルと規定

ここで説明した目的のために、各クラスは、そのスーパー・タイプによって定義されたインタフェースまたは規約を実装し、拡張します。 クラスの新しいバージョン、たとえば、foo'は、fooのための規約を維持する必要があり、インタフェースを拡張したり、その実装を修正したりできます。

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

5.5 互換性のあるJavaの型展開

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

直列化されたオブジェクト・ストリームのバージョン管理を設計する場合の基本的な項目を、次に示します。

5.6 直列化に影響する型変更

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

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

5.6.1 互換性のない変更

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

5.6.2 互換性のある変更

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