この記事では、Javaにおけるオブジェクトのシリアル化と敏arializationについて説明します。あなたの参照のために全員のためにそれを共有してください。詳細は次のとおりです。
1。はじめに
オブジェクトのシリアル化とは、オブジェクトをバイトのシーケンスに変換するプロセスを指し、一方、脱派化とは、バイトのシーケンスに基づいてオブジェクトを復元するプロセスです。
通常、シリアル化は次のシナリオで使用されます。
1.オブジェクトを永続的に保存し、オブジェクトのバイトシーケンスをローカルファイルに保存します。
2。それらをシリアル化することにより、ネットワーク内のオブジェクトを渡します。
3.シリアル化を通じてプロセス間でオブジェクトを渡します。
オブジェクトが属するクラスは、シリアル化するためにシリアル化可能または外部化可能なインターフェイスを実装する必要があります。シリアル化可能なインターフェースを実装するクラスでは、シリアル化と脱登場は、外部化可能なインターフェイスを継承し、外部化可能なインターフェイスクラスを完全に制御することです。
java.io.objectOutputStreamはオブジェクト出力ストリームを表し、そのメソッドwriteObject(オブジェクトOBJ)はオブジェクトのシリアル化を実現し、取得したバイトシーケンスをターゲット出力ストリームに書き込むことができます。
java.io.objectinputStreamはオブジェクト入力ストリームを表し、そのreadObject()メソッドは、ソース入力ストリームからバイトのシーケンスを読み取り、オブジェクトに脱出して返すことができます。
2。シリアル化するいくつかの方法
顧客のクラスが定義されていると仮定します。顧客のシリアル化方法に応じて、次のシリアル化方法がある場合があります。
1.シリアル化可能な未定義のreadObjectおよびwriteObjectメソッドを実装します
ObjectOutputStreamはJDKを使用して、デフォルトで顧客オブジェクトの非転換インスタンス変数をシリアル化します。
ObjectInputStreamは、JDKデフォルトメソッドを使用して、顧客オブジェクトの非転換インスタンス変数を脱皮化します。
2。シリアル化可能な実装と、readObjectおよびwriteObjectメソッドを定義します
ObjectOutputStreamは、顧客クラスのWriteObject(objectOutputStream)メソッドを呼び出して、顧客オブジェクトの非転換インスタンス変数をシリアル化します。
ObjectInputStreamは、顧客クラスのReadObject(ObjectInputStream in)メソッドを呼び出して、顧客オブジェクトの非転移インスタンス変数を脱却します。
3.外部化可能な実装、reageExterternalおよびwriteexternalメソッドを定義します
ObjectOutputStreamは、顧客クラスのWriteExternalメソッドを呼び出して、顧客オブジェクトの非転換インスタンス変数をシリアル化します。
ObjectInputStreamまず、顧客クラスのパラメーターレスコンストラクターを介してオブジェクトをインスタンス化し、次に、reagreexternalメソッドを使用して顧客オブジェクトの非転換インスタンス変数を脱上化します。
3。シリアル化可能なインターフェイス
このクラスは、java.io.serializableインターフェイスを実装することにより、シリアル化機能を有効にします。このインターフェイスを実装していないクラスは、それらの状態をシリアル化または脱必要にすることはできません。シリアル化可能なクラスのすべてのサブタイプ自体はシリアル化可能です。シリアル化インターフェイスにはメソッドやフィールドがなく、シリアル化可能なセマンティクスを識別するためにのみ使用されます。
脱出プロセス中、非シリアル化クラスのフィールドは、クラスの一般的または保護されたパラメーターのないコンストラクターを使用して初期化されます。シリアル化可能なサブクラスは、パラメーターレスコンストラクターにアクセスできる必要があります。シリアル化可能なサブクラスになる可能性のあるフィールドは、ストリームから復元されます。
クラスビューを通過するとき、シリアル化可能なインターフェイスをサポートしていないオブジェクトに遭遇する可能性があります。この場合、NotserializableExceptionがスローされ、シリアル化できないクラスが識別されます。
1。正確な署名
シリアル化および脱介入中に特別な処理を必要とするクラスは、次の正確な署名を使用して特別な方法を実装する必要があります。
private void writeObject(java.io.objectoutputStream out)はioExceptionをスローします
private void readobject(java.io.objectinputStream in)は、ioException、classNotFoundExceptionをスローします。
private void readObjectNodata()はObjectStreamExceptionをスローします。
writeObjectメソッドは、特定のクラスのオブジェクトの状態を作成する責任があり、対応するReadObjectメソッドが復元できるようにします。オブジェクトのフィールドを保存するためのデフォルトのメカニズムは、Callued.DefaultWriteObjectを呼び出すことで呼び出すことができます。この方法自体は、スーパークラスまたはサブクラスに属する状態を巻き込む必要はありません。状態は、writeObjectメソッドを使用して個々のフィールドをObjectputStreamに書き込むか、基本的なデータ型のDataUtputでサポートされているメソッドを使用して保存できます。
ReadObjectメソッドは、ストリームからクラスフィールドを読み取り、復元する責任があります。 in.defaultreadobjectを呼び出して、デフォルトのメカニズムを呼び出して、オブジェクトの非静的および非容量のフィールドを復元することができます。 DefaulTreadObjectメソッドは、ストリーム内の情報を使用して、現在のオブジェクトの対応する指定されたフィールドに保存されるストリーム内のオブジェクトのフィールドを割り当てます。これは、クラスの進化後に新しいフィールドを追加する必要がある状況に対処するために使用されます。この方法自体は、スーパークラスまたはサブクラスに属する状態を巻き込む必要はありません。状態は、writeObjectメソッドを使用して個々のフィールドをObjectputStreamに書き込むか、基本的なデータ型のDataUtputでサポートされているメソッドを使用して保存できます。
シリアル化ストリームが指定されたクラスを脱必要なスーパークラスとしてリストしていない場合、ReadObjectNodataメソッドは、特定のクラスのオブジェクト状態の初期化を担当します。これは、受信機が使用する脱色インスタンスクラスが送信者とは異なり、レシーバーバージョンによって拡張されたクラスが送信者バージョンによって拡張されたクラスではない場合に発生します。また、シリアル化ストリームが改ざんされている場合にも発生します。
ストリームにオブジェクトを作成する場合、使用する代替オブジェクトのシリアル化可能なクラスを指定する必要があります。また、正確な署名でこの特別な方法を実装する必要があります。
Any-Access-Modifier Object writereplace()はObjectStreamExceptionをスローします。
このメソッドが存在し、シリアル化されたオブジェクトのクラスで定義されたメソッドでアクセスできる場合、このライタープレイスメソッドはシリアル化によって呼び出されます。したがって、この方法は、プライベート、保護された、パッケージプライベートアクセスを持つことができます。このメソッドへのサブクラスアクセスは、Javaアクセスルールに従います。
ストリームからクラスのインスタンスを読むときは、代替クラスがこの特別な方法を実装するために使用する正確な署名を指定する必要があります。
Any-Access-Modifier Object ReadResolve()はObjectStreamExceptionをスローします。
このReadResolveメソッドは、WriterePlaceと同じ呼び出しルールとアクセスルールに従います。
クラスがReadResolveメソッドを定義する場合、ReadResolveメソッドは脱介入の終わりに呼び出され、メソッドによって返されるオブジェクトは脱介入の最終結果です。
2.SerialVersionUid
Serialization Runtimeは、SerialVersionuidというバージョン番号を使用して、各シリアル化可能なクラスに関連付けられます。これは、互換性のあるクラスにロードされたシリアル化オブジェクトの送信者と受信者を確認するために使用されます。受信者が、対応する送信者のバージョン番号とは異なるオブジェクトのクラスのシリアルバージョンをロードすると、崩壊は無効なクラスセックスになります。シリアル化可能なクラスは、「SerialVersionUid」という名前のフィールド(そのフィールドは静的な最終的な長いフィールドでなければならない)を宣言することにより、独自のSerialVersionUidを明示的に宣言できます。
Any-Access-Modifier static final long serialversionuid = 42l;
SerializableクラスがSerialVersionUidを明示的に宣言しない場合、シリアル化ランタイムは、「Java(TM)オブジェクトシリアル化仕様」で説明されているように、クラスのさまざまな側面に基づいてクラスのデフォルトのシリアルバージョン値を計算します。ただし、デフォルトのシリアルバージョンルイドの計算はクラスの詳細に非常に敏感であり、コンパイラの実装によって大きく異なるため、すべてのシリアル化可能なクラスがシリアルバージョンの値を明示的に宣言することを強くお勧めします。結果として生じる可能性があります。したがって、さまざまなJavaコンパイラ全体でシリアルバージョン値間の一貫性を確保するには、シリアル化されたクラスは明示的なシリアルバージョン値を宣言する必要があります。また、そのような宣言はクラスを直接宣言するためにのみ使用されるため、宣言宣言のシリアルバージョンを表示するためにプライベート修飾子を使用して、継承されたメンバーとしてのシリアルバージョン使用フィールドは役に立たないため、強くお勧めします。アレイクラスは、明示的なSerialVersionUidを宣言することはできないため、常にデフォルトの計算値を持っていますが、配列クラスはSerialVersionUid値要件と一致しません。
3.エクスタル化可能なインターフェイス
外部化可能は、外部化可能なインターフェイスを実装するクラスのシリアル化の拡張です。
シリアル化中にクラスのメソッドWriteExternalを呼び出し、Exemexternal Methodを脱上化します。
したがって、クラスのパラメーターレスコンストラクターは、最初に呼ばれます。したがって、シリアル化を実装するための外部化可能なインターフェイスを実装する場合、パラメーターレスコンストラクターが提供されます。
第4、要約
クラスがシリアル化可能なインターフェイスを実装する限り、デフォルトのシリアル化方法が採用されている場合、そのインスタンスはシリアル化できます。一般に、継承用に特別に設計されたクラスは、親クラスがシリアル化可能なインターフェイスを実装すると、すべてのサブクラスがシリアル化可能であるため、シリアル化可能なインターフェイスを実装しないようにする必要があります。
デフォルトのシリアル化方法の欠点:
1.オブジェクトの開示には適していない機密データを直接シリアル化することは安全ではありません。
2.オブジェクトのメンバー変数が正しい制約を満たしているかどうかを確認し、データを改ざんし、異常な動作を引き起こす可能性があります。
3。オブジェクトグラフの再帰トラバーサルが必要です。
4.クラスのインターフェイスをクラスの内部実装によって制約し、クラスのアップグレードとメンテナンスを制限します。
シリアル化可能なインターフェイスのprivate object()およびreadobject()を実装するか、外部化可能なインターフェイスを実装し、writeexternal()およびreadexternal()メソッドを実装し、公開型パラメーターレスコンストラクターにシリアル化プロセスを制御する2つの方法を提供することによりデフォルトのシリアル化方法の欠点を効果的に回避できます。
この記事がすべての人のJavaプログラムのデザインに役立つことが期待されています。