Java 

オブジェクト直列化の機能拡張

ドキュメントの目次
オブジェクト直列化の機能拡張
64K を超える文字列を直列化できる (1.3 以降)
1.3 より前は、64K を超える文字列を直列化しようとすると、java.io.UTFDataFormatException がスローされました。1.3 では、64K を超える文字列を直列化できるように、直列化プロトコルが拡張されました。ただし、1.2 以前の JVM で、1.3 互換の JVM で記述された長い文字列を読み込もうとすると、1.2 以前の JVM に java.io.StreamCorruptedException が返されます。

直列化のパフォーマンスの向上 (1.3 以降)
全般的なパフォーマンスを向上させるため、直列化にいくつかの変更が加えられました。
  • 不要なメモリ割り当ておよび同期/メソッド呼び出しのオーバーヘッドを減らすために、UTF 文字列の読み取り/書き込みが最適化されました。
  • プリミティブデータ配列の読み取りおよび書き込み用のコードが簡素化されました。ネイティブメソッドの呼び出 し回数を最小にするため、float および double 型配列の読み取り/書き込みが再実装されました。
  • 内部バッファリングが改善されました。
  • 異なるネイティブメソッドの呼び出し回数を最小にするため、プリミティブフィールド値の取得/設定用リフレク ション操作がバッチ処理化されました。

例外報告の改善 (1.3 以降)
直列化復元のクラス解決処理中にクラスが検出されなかった場合は、汎用的な例外でなく、元の java.lang.ClassNotFoundException がスローされるようになりました。この結果、エラーについて詳細な情報を得られるようになりました。また、直列化 復元の例外では、直列化復元中の上位クラスが報告されていましたが、検出されなかった実際のクラスの名前が保存さ れて報告されるようになりました。たとえば、RMI 呼び出しを行なったときに、スタブクラスは検出されたが、リモートインタフェースクラスが検出されないことがあり ます。この場合、現在の直列化機構では、検出されなかったクラスがそのインタフェースクラスであると正しく報告さ れ、スタブクラスが検出されなかったという誤った報告は行われません。

java.io.ObjectOutputStream.writeClassDescriptor
java.io.ObjectInputStream.readClassDescriptor (1.3 以降)
java.io.ObjectStreamClass クラス記述子の直列化表現をカスタマイズする方法を提供するため、writeClassDescriptor メソッドと readClassDescriptor メソッドが追加されました。java.io.ObjectStreamClass のインスタンスの直列化が必要なときには、writeClassDescriptor が呼び出されます。また、writeClassDescriptor は、ObjectStreamClass を直列化ストリームに書き込まなければなりません。逆に、直列化ストリーム内の次の項目として、ObjectInpu tStream により ObjectStreamClass のインスタンスが予期される場合、readClassDescriptor が呼び出されます。ObjectOutputStream および ObjectInputStream のサブクラスは、これらのメソッドをオーバーライドすることにより、クラス記述子をアプリケーション固有の形式で 送信できます。詳細は、「Java オブジェクト直列化仕様」の 2.1 および 3.1 節を参照してください。

java.io.ObjectOutputStream.annotateProxyClass
java.io.ObjectInputStream.resolveProxyClass (1.3 以降)
これらのメソッドは、目的の点で ObjectOutputStream.annotateClass および ObjectInputStream.resolveClass に類似しています。ただし、これらのメソッドは、非プロキシクラスとは対照的に、動的プロキシクラス (java.lang.reflect.Proxy を参照) に適用される点が異なります。ObjectOutputStream のサブクラスは、annotateProxyClass をオーバーライドすることにより、カスタムデータを動的プロキシクラスの記述子と共にストリーム内に格納できます 。ObjectInputStream サブクラスは、次に resolveProxyClass をオーバーライドすることにより、指定されたプロキシクラス記述子と関連付けるローカルクラスの選択にカスタムデ ータを利用します。詳細は、「Java オブジェクト直列化仕様」のセクション 4 を参照してください。

javadoc ツールタグ @serial@serialField、および @serialData (1.2 以降)
クラスの直列化された形式を文書化する手段を提供するために、javadoc タグ @serial@serialField および @serialData が、追加されました。javadoc は、これらのタグの内容を基にして直列化の仕様を生成します。詳細は、「Java オブジェクト直列化仕様」の 1.6 節を参照してください。

プロトコルのバージョン管理 (1.2 以降)
1.2 以前では、java.io.Externalizable インタフェースを実装するオブジェクトのクラスを使用できない場合に、オブジェクト直列化で使用するプロトコルが 、そのオブジェクトをスキップする機能はありませんでした。1.2 では、この欠陥を解決する新たなプロトコルバージョンが追加されました。下位互換性を保証するため、Object OutputStream および ObjectInputStream は、新旧のどちらのプロトコルで書き込まれた直列化ストリームに対しても、読み取りおよび書き込みが可能です。互 換性に関する問題の詳細は、「Java オブジェクト直列化仕様」の 6.3 節を参照してください。

クラス定義された writeReplace および readResolve メソッド (1.2 以降)
1.2 以降、クラスは、writeReplace および readResolve メソッドを定義できるようになりました。これらのメソッドを使用することにより、指定されたクラスのインスタンス は、直列化および直列化復元時にそのインスタンス自体の置換を指定できます。これらのメソッドに必須の署名、およ び詳細については、「Java オブジェクト直列化仕様」の 2.5 節 および 3.6 節で説明されています。

java.io.ObjectOutputStream.writeObjectOverridejava.io.ObjectInputStream.readObjectOverride< /code> (1.2 以降)
1.2 以降、ObjectOutputStream および ObjectInputStream のサブクラスは、writeObjectOverride および readObjectOverride メソッドをオーバーライドすることにより、カスタム直列化プロトコルを実装できます。これらのメソッドが呼び出さ れるのは、ObjectOutputStream/ObjectInputStream サブクラスがアクセス権 java.io.SerializablePermission("enableSubclassImplementation") を保持し、ObjectOutputStream/ObjectInputStream の引数を持たないコンストラクタを呼び出す場合だけです。詳細は、「Java オブジェクト直列化仕様」の 2.1 節および 3.1 節を参照してください。

セキュリティアクセス権のチェック (1.2 以降)
ObjectOutputStream および ObjectInputStream のサブクラスは、継承したメソッドをオーバーライドすることにより、直列化プロセスの特定の局面への「フック」を 取得できます。1.2 以降、オブジェクト直列化では、1.2 のセキュリティモデルを使用して、サブプロセスが特定のフックをオーバーライドするための適切なアクセス権を保持 しているかどうか確認しています。アクセス権 java.io.SerializablePermission("enableSubclassImplementation") および java.io.SerializablePermission("enableSubstitution") は、ObjectOutputStream.writeObjectOverride メソッド、ObjectOutputStream.replaceObject メソッド、ObjectInputStream.readObjectOverride メソッド、およびObjectInputStream.resolveObject メソッドが直列化の過程で呼び出されるかどうかを管理します。詳細は、「Java オブジェクト直列化仕様」の 2.1 節および 3.1 節を参照してください。

クラスの直列化可能フィールドの定義 (1.2 以降)
デフォルトでは、直列化可能クラスのインスタンスを直列化する際に、その直列化可能クラスの非 static および非 transient フィールドすべての値が書き込まれます。1.2 では、クラスからこの処理をより細かく制御することのできる機構が導入されました。特別なフィールドである serialPersistentFields を宣言することにより、直列化可能クラスは、クラス (またはサブクラス) のインスタンスの直列化時に書き込まれるフィールドを決定できます。この機能により、クラス内の実際のフィールド に直接関連しない直列化可能フィールドを、クラスから「定義」できるようにもなりました。この機能を直列化可能フ ィールド API (後述) と共に使用することにより、クラスの直列化表現を変更せずに、クラスに対しフィールドを追加または削除できます。 詳細は、「Java オブジェクト直列化仕様」の 1.5 節および 1.7 節を参照してください。

直列化可能フィールド API (1.2 以降)
1.2 で導入された直列化可能フィールド API を使用すると、クラス定義の writeObject/readObject メソッドから、直列化可能フィールドの値を、名前とタイプを使って明示的に設定して取得できます。クラスが、以前 のクラスバージョンとの下位互換性を必要とする場合に、この API は特に有用です。これは、クラスによっては、現在のクラスに直接マッピングできない一連の直列化可能フィールドを 以前のバージョンで定義しているものがあるためです。この場合、新規バージョンのクラスでカスタムの writeObject および readObject メソッドを定義します。これらのメソッドは、(新規) クラスの指定インスタンスの内部状態を「以前の」直列化形式に変換できます。また、その逆も可能です。詳細は、「 Java オブジェクト直列化仕様」の 1.7 節を参照してください。
* この Web サイトで使用されている「Java Virtual Machine」または「JVM」という用語は、Java プラットフォーム用の仮想マシンを意味します。
Copyright © 1999 Sun Microsystems, Inc.All Rights Reserved.
コメントの送付先: rmi-comments@java.sun.com 
Sun