ここでは、Java™ SE Development Kit 6 (JDK) 以前に行われた直列化の拡張機能について説明します。現行リリースでの拡張機能については、「Java SE Development Kit 6 での直列化の変更と拡張」を参照してください。
Enum.valueOf メソッドが呼び出されます。ObjectInputStream.readClassDescriptor メソッドによってスローされる ClassNotFoundException は、StreamCorruptedException として ObjectInputStream.readObject のトップレベルの呼び出し側に反映され、その原因は空であることだとされました。現在は、InvalidClassException としてトップレベルの呼び出し側に反映されるようになり、その原因は元の ClassNotFoundException となります。ObjectStreamClass.lookup メソッドの Class 引数で表されるクラスの静的初期化子内で、このメソッドが呼び出された場合にデッドロックする可能性がありました。この場合、デッドロックが発生することはなくなりました。Serializable インタフェースの javadoc が拡張され、serialVersionUID の役割と使用方法をさらに詳細に指定できるようになり、また、直列化可能なクラスの serialVersionUID を明示的に指定する必要性が明確となりました。これらの API は、含まれる配列オブジェクトをセキュアな方法でより効率的に読み取るために使用できます。『Java オブジェクト直列化仕様』のセクション A.6「非共有の直列化復元されたオブジェクトの保護」を参照してください。
同様に、J2SE 1.4.0 から、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 がスローされました。1.3 では、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 (1.3 以降)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 (1.3 以降)ObjectOutputStream.annotateClass および ObjectInputStream.resolveClass に類似しています。ただし、これらのメソッドは、非プロキシクラスとは対照的に動的プロキシクラス (java.lang.reflect.Proxy を参照) に適用される点が異なります。ObjectOutputStream のサブクラスは、annotateProxyClass をオーバーライドすることにより、カスタムデータを動的プロキシクラスの記述子とともにストリーム内に格納できます。ObjectInputStream サブクラスは、次に resolveProxyClass をオーバーライドすることにより、指定されたプロキシクラス記述子と関連付けるローカルクラスの選択にカスタムデータを利用します。詳細は、『Java オブジェクト直列化仕様』のセクション 4 を参照してください。@serial、@serialField、および @serialData (1.2 以降)@serial、@serialField、および @serialData が追加されました。javadoc は、これらのタグの内容を基にして直列化の仕様を生成します。詳細は、『Java オブジェクト直列化仕様』のセクション 1.6 を参照してください。java.io.Externalizable インタフェースを実装するオブジェクトのクラスを使用できない場合に、そのオブジェクトをスキップする機能はありませんでした。1.2 では、この欠陥を解決する新たなプロトコルバージョンが追加されました。下位互換性を確保するため、ObjectOutputStream および ObjectInputStream は、どちらのプロトコルで書き込まれた直列化ストリームに対しても、読み取りおよび書き込みが可能です。使用されるプロトコルバージョンは、ObjectOutputStream.useProtocolVersion メソッドを呼び出すことにより選択できます。互換性に関する問題の詳細は、『Java オブジェクト直列化仕様』のセクション 6.3 を参照してください。writeReplace および readResolve メソッド (1.2 以降)writeReplace および readResolve メソッドを定義できるようになりました。これらのメソッドを使用することにより、指定されたクラスのインスタンスは、直列化および直列化復元時にそのインスタンス自体の置換を指定できます。これらのメソッドに必須のシグニチャー、および詳細については、『Java オブジェクト直列化仕様』のセクション 2.5 および 3.6 を参照してください。java.io.ObjectOutputStream.writeObjectOverride、java.io.ObjectInputStream.readObjectOverride (1.2 以降)ObjectOutputStream および ObjectInputStream のサブクラスは、writeObjectOverride および readObjectOverride メソッドをオーバーライドすることにより、カスタム直列化プロトコルを実装できます。これらのメソッドが呼び出されるのは、ObjectOutputStream/ObjectInputStream サブクラスがアクセス権 java.io.SerializablePermission("enableSubclassImplementation") を保持し、ObjectOutputStream/ObjectInputStream の引数を持たないコンストラクタを呼び出す場合だけです。詳細は、『Java オブジェクト直列化仕様』のセクション 2.1 および 3.1 を参照してください。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 を参照してください。serialPersistentFields を宣言することにより、直列化可能クラスは、クラスまたはサブクラスのインスタンスの直列化時に書き込まれるフィールドを決定できます。この機能により、クラス内の実際のフィールドに直接関連しない直列化可能フィールドを、クラスから「定義」できるようにもなりました。この機能を次に説明する直列化可能フィールド API とともに使用することにより、クラスの直列化表現を変更せずに、クラスに対しフィールドを追加または削除できます。詳細は、『Java オブジェクト直列化仕様』のセクション 1.5 および 1.7 を参照してください。writeObject/readObject メソッドから、直列化可能フィールドの値を、名前と型によって明示的に設定して取得できます。クラスに以前のクラスバージョンとの下位互換性が必要な場合は、この API は特に有用です。これは、クラスによっては、現在のクラスのフィールドに直接マッピングできない一連の直列化可能フィールドを以前のバージョンで定義しているものがあるためです。この場合、新規バージョンのクラスでカスタムの writeObject および readObject メソッドを定義します。これらのメソッドは、(新規) クラスの指定されたインスタンスの内部状態を「以前の」直列化形式に変換できます。また、その逆も可能です。詳細は、『Java オブジェクト直列化仕様』のセクション 1.7 を参照してください。