次の項目について説明します。
java.io.ObjectStreamClass.lookupAnyClassの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.readClassDescriptorjava.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.resolveProxyClassObjectOutputStream.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.readObjectOverrideObjectOutputStreamおよび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を参照してください。