次の項目について説明します。
java.io.ObjectStreamClass.lookupAny
Class
のObjectStreamClass
インスタンスをプログラムで取得することは困難でした。しかし、クラス記述子のストリーム形式をカスタマイズするときは、そのようにすることが望ましい場合もあります(詳細は、4413615を参照)。新しいメソッドObjectStreamClass.lookupAnyをこのために使用できるようになりました。ObjectOutputStream
およびObjectInputStream
の直列化可能クラスおよびサブクラスを直列化操作で使用後しばらくたっても、これらのクラスへの強い参照がある場合がありました。このためこれらを定義するクラス・ローダーのガベージ・コレクションが無期限に遅れる可能性がありました。このバグを修正するために、直列化の実装で内部キャッシュが再構築されました。Enum.valueOf
メソッドが呼び出されます。ObjectInputStream.readClassDescriptor
メソッドによってスローされるClassNotFoundException
は、StreamCorruptedException
としてObjectInputStream.readObject
のトップレベルの呼出し側に反映され、その原因は空であることだとされました。現在は、InvalidClassException
としてトップ・レベルの呼出し側に反映されるようになり、その原因は元のClassNotFoundException
となります。ObjectStreamClass.lookup
メソッドのClass
引数で表されるクラスの静的初期化子内で、このメソッドが呼び出された場合にデッドロックする可能性がありました。この場合、デッドロックが発生することはなくなりました。Serializable
インタフェースのjavadocが拡張され、serialVersionUID
の役割と使用方法をさらに詳細に指定できるようになり、また、直列化可能なクラスのserialVersionUID
を明示的に指定する必要性が明確となりました。これらのAPIは、含まれる配列オブジェクトをセキュアな方法でより効率的に読み取るために使用できます。
ObjectInputStream.readFieldsまたはObjectInputStream.readUnsharedをオーバーライドするサブクラスでObjectInputStreamの引数を1つ取るpublicのコンストラクタを直接的または間接的に呼び出すとき、"enableSubclassImplementation" SerializablePermissionが必要になりました。
このような変更は、アプリケーションの大部分には影響がありません。ただし、putFieldsまたはreadFieldsメソッドをオーバーライドするが直列化インフラストラクチャの残りの部分はオーバーライドしないObjectInputStreamサブクラスやObjectOutputStreamサブクラスは影響を受けます。
private void readObjectNoData() throws ObjectStreamException;readObjectNoData()メソッドはクラス定義メソッドreadObject()と似ています。ただし、直列化復元中のオブジェクトのスーパー・クラスのクラス記述子およびそのクラス記述子で記述されるオブジェクト・データが、直列化ストリームにない場合に呼び出される(定義されている場合)という点が異なります。つまり、次のとおりです。クラスCのオブジェクトOが直列化復元中で、Oを直列化復元しているVM内のCのスーパー・クラスがSである場合、Oの直列復元中にObjectInputStreamによってS.readObjectNoData()が呼び出されるのは、次の条件が成立する場合のみです。
詳細は、ObjectInputStreamのAPI仕様でクラスの説明を参照してください。
java.io.UTFDataFormatException
がスローされました。このリリースでは、64Kを超える文字列を直列化できるように、直列化プロトコルが拡張されました。ただし、1.2以前のJVMで、1.3に準拠したJVMで記述された長い文字列を読み込もうとすると、1.2以前のJVMはjava.io.StreamCorruptedException
を受け取ります。java.lang.ClassNotFoundException
がスローされるようになりました。この結果、エラーについて詳細な情報を得られるようになりました。また、直列化復元の例外では、直列化復元中の上位クラスが報告される代わりに、検出されなかった元のクラスの名前が保存されて報告されるようになりました。たとえば、RMI呼出しを行うと、スタブ・クラスは検出されるが、リモート・インタフェース・クラスが検出されないことがあります。この場合、現在の直列化メカニズムでは、検出されなかったクラスがそのインタフェース・クラスであると正しく報告され、スタブ・クラスが検出されなかったという誤った報告は行われません。java.io.ObjectOutputStream.writeClassDescriptor
、java.io.ObjectInputStream.readClassDescriptor
java.io.ObjectStreamClass
クラス記述子の直列化表現をカスタマイズする方法を提供するために、writeClassDescriptor
メソッドとreadClassDescriptor
メソッドが追加されました。writeClassDescriptor
は、java.io.ObjectStreamClass
のインスタンスの直列化が必要なときに呼び出され、ObjectStreamClass
を直列化ストリームに書き込む役割を果たします。逆に、直列化ストリーム内の次の項目として、ObjectInputStream
がObjectStreamClass
インスタンスを要求しているときは、readClassDescriptor
が呼び出されます。ObjectOutputStream
およびObjectInputStream
のサブクラスは、これらのメソッドをオーバーライドすることにより、クラス記述子をアプリケーション固有の形式で送信できます。詳細は、『Javaオブジェクト直列化仕様』のセクション2.1および3.1を参照してください。java.io.ObjectOutputStream.annotateProxyClass
、java.io.ObjectInputStream.resolveProxyClass
ObjectOutputStream.annotateClass
およびObjectInputStream.resolveClass
と似ています。ただし、これらのメソッドは、非プロキシ・クラスとは対照的に動的プロキシ・クラス(java.lang.reflect.Proxy
を参照)に適用される点が異なります。ObjectOutputStream
のサブクラスは、annotateProxyClass
をオーバーライドすることにより、カスタム・データを動的プロキシ・クラスの記述子とともにストリーム内に格納できます。ObjectInputStream
サブクラスは、次にresolveProxyClass
をオーバーライドすることにより、指定されたプロキシ・クラス記述子と関連付けるローカル・クラスの選択にカスタム・データを利用します。詳細は、『Javaオブジェクト直列化仕様』のセクション4を参照してください。@serial
、@serialField
、および@serialData
@serial
、@serialField
、および@serialData
が追加されました。javadocは、これらのタグの内容を基にして直列化の仕様を生成します。詳細は、『Javaオブジェクト直列化仕様』のセクション1.6を参照してください。java.io.Externalizable
インタフェースを実装するオブジェクトのクラスを使用できない場合に、そのオブジェクトをスキップする機能はありませんでした。このリリースでは、この欠陥を解決する新たなプロトコル・バージョンが追加されました。下位互換性を確保するため、ObjectOutputStream
およびObjectInputStream
は、どちらのプロトコルで書き込まれた直列化ストリームに対しても、読取りおよび書込みが可能です。使用されるプロトコル・バージョンは、ObjectOutputStream.useProtocolVersion
メソッドを呼び出すことにより選択できます。互換性に関する問題の詳細は、『Javaオブジェクト直列化仕様』のセクション6.3を参照してください。writeReplace
およびreadResolve
メソッドwriteReplace
およびreadResolve
メソッドを定義できます。これらのメソッドを使用することにより、指定されたクラスのインスタンスは、直列化および直列化復元時にそのインスタンス自体の置換を指定できます。これらのメソッドに必須のシグネチャ、および詳細については、『Javaオブジェクト直列化仕様』のセクション2.5および3.6を参照してください。java.io.ObjectOutputStream.writeObjectOverride
、java.io.ObjectInputStream.readObjectOverride
ObjectOutputStream
およびObjectInputStream
のサブクラスで、writeObjectOverride
およびreadObjectOverride
メソッドをオーバーライドすることにより、カスタム直列化プロトコルを実装できます。これらのメソッドが呼び出されるのは、ObjectOutputStream/ObjectInputStream
サブクラスがアクセス権java.io.SerializablePermission("enableSubclassImplementation")
を保持し、ObjectOutputStream/ObjectInputStream
の引数を持たないコンストラクタを呼び出す場合だけです。詳細は、『Javaオブジェクト直列化仕様』のセクション2.1および3.1を参照してください。ObjectOutputStream
およびObjectInputStream
のサブクラスは、継承したメソッドをオーバーライドすることにより、直列化プロセスの特定の局面への「フック」を取得できます。このリリース以降、オブジェクト直列化では、1.2のセキュリティ・モデルを使用して、サブクラスが特定のフックをオーバーライドするための適切なアクセス権を保持しているかどうかを確認しています。アクセス権java.io.SerializablePermission("enableSubclassImplementation
")およびjava.io.SerializablePermission("enableSubstitution
")は、ObjectOutputStream.writeObjectOverride
メソッド、ObjectOutputStream.replaceObject
メソッド、ObjectInputStream.readObjectOverride
メソッド、およびObjectInputStream.resolveObject
メソッドが直列化の過程で呼び出されるかどうかを管理します。詳細は、『Javaオブジェクト直列化仕様』のセクション2.1および3.1を参照してください。serialPersistentFields
を宣言することにより、直列化可能クラスは、クラスまたはサブクラスのインスタンスの直列化時に書き込まれるフィールドを決定できます。この機能により、クラス内の実際のフィールドに直接関連しない直列化可能フィールドを、クラスから「定義」できるようにもなりました。この機能を次に説明する直列化可能フィールドAPIとともに使用することにより、クラスの直列化表現を変更せずに、クラスに対しフィールドを追加または削除できます。詳細は、『Javaオブジェクト直列化仕様』のセクション1.5および1.7を参照してください。writeObject
またはreadObject
メソッドから、直列化可能フィールドの値を、名前と型によって明示的に設定して取得できます。クラスに以前のクラス・バージョンとの下位互換性が必要な場合は、このAPIは特に有用です。これは、クラスによっては、現在のクラスのフィールドに直接マッピングできない一連の直列化可能フィールドを以前のバージョンで定義しているものがあるためです。この場合、新規バージョンのクラスでカスタムのwriteObject
およびreadObject
メソッドを定義します。これらのメソッドは、(新規)クラスの指定されたインスタンスの内部状態を「以前の」直列化形式に変換できます。また、その逆も可能です。詳細は、『Javaオブジェクト直列化仕様』のセクション1.7を参照してください。