まず、基本的な概念
シリアライズとデシリアライズは何1
(は1)は、Java直列化は、Javaは、バイトの配列を処理するオブジェクトを変換して、JavaバイトシーケンスをデシリアライズするためにJavaオブジェクトの回収プロセスを指す指します。
(2)**の配列:オブジェクトは、オブジェクトの整合性を確保して送信する場合**オブジェクトシリアライゼーション主な用途は、伝送及び記憶装置です。シリアル化は、伝送のために順序付けられたバイトストリームにオブジェクトであるか、またはネットワーク上のローカルファイルに保存されています。直列化されたバイトストリームはJavaオブジェクトと関連する記述情報の状態を保存します。直列化機構の中心的な役割は、オブジェクトの状態の保存と再構築です。
(3)**デシリアライズ:取得対象クライアント**再生物体デシリアライズによりバイトストリームに格納されたオブジェクトの状態と記述情報に従って、ストリームバイトまたはネットワーク上のファイルからシリアライズ。
(4)本質的には、物理的オブジェクトの配列は、特定のフォーマットに従って秩序状態バイトストリームに書き込まれ、デシリアライズは、オブジェクトの状態を復元するように命じたバイトストリームから再構成されたオブジェクトです。
2.なぜシリアライズとデシリアライズが必要なのか
我々は2つのプロセスがリモートで通信するとき、あなたはテキスト、画像、オーディオ、ビデオなどを含むデータの相互様々なタイプを、送信することができ、これらのデータは、ネットワークを介して送信バイナリシーケンスの形態であることを知っています。
だから、2つのJavaは、プロセス間のオブジェクト転送を達成する能力を通信するために処理するとき?答えはイエスです!どのようにそれを行うには?これは、Javaのシリアライゼーションとのデシリアライズが必要です!
換言すれば、一方では、Javaオブジェクトを変換するセンダ必要はバイトのシーケンスであり、そして、ネットワーク上に送信、他の手は、受け手は、バイトシーケンスからJavaオブジェクトを回復する必要があります。
我々は、Javaのシリアライズとデシリアライズする理由を明確にする必要があるとき、私たちは自然のJava直列化のメリットをお勧めします。まず、その利点は、データを永続達成するために、データが永続的にディスク(通常はファイルに格納されている)へのシリアライゼーションを保存することができ、そして第二に、遠隔通信の配列、すなわちを使用することは、ネットワークバイト上のオブジェクトを転送しますシーケンス。
次のように一般的には、要約することができます。
ローカルファイルまたはデータベース内のバイトの永続オブジェクト記憶標的配列保存(1)、
(2)オブジェクトのバイトストリームにおけるネットワーク内の送信及び受信のためにシリアライズすることにより、
(3)の配列オブジェクトを渡すプロセス間。
3、直列化アルゴリズムは、一般的に次のことを行うための手順に従います:
(1)関連データ出力クラス・オブジェクト・インスタンス・メタデータ。
再帰ないスーパークラスまで出力の(2)の説明スーパー。
クラスメタデータが終了した後、(3)は、実際のデータ値のスーパークラスから最上位オブジェクト・インスタンスの出力を開始し始めます。
再帰的なインスタンストップダウンからデータ(4)出力
二つは、Javaは、シリアライズとデシリアライズを実装する方法
1、JDKのクラスライブラリのシリアライズとデシリアライズAPI
(1)java.io.ObjectOutputStreamの:出力ストリームを表すオブジェクト。
それのwriteObject(オブジェクトobj)メソッドは、オブジェクトOBJパラメーターが指定されたターゲット出力ストリームに書き込まれたバイトの結果の配列をシリアライズすることができます。
(2)java.io.ObjectInputStream:入力ストリームを表すオブジェクト。
それのreadObject()メソッドは、次に、それらがデシリアライズする対象となる入力ストリームのバイトのソースシーケンスを読み出し、リターン。
2、シリアル化の要件を実装
唯一のオブジェクトクラスインタフェース直列化または外部化を達成することによってシリアライズ、または例外をスローすることができます!
Javaオブジェクトのシリアル化および逆シリアル化プロセスを実現するための3、
シリアル化するためにあるUserクラスを、と仮定すると、あなたは、次の3つの方法を持つことができます。
Userクラスが実装する直列化インターフェースは、次のように直列化および非直列化することができる場合にのみ、(1)
デフォルトの直列化、非transientインスタンス変数ユーザオブジェクトのシリアル化を使用してObjectOutputStream。
ObjcetInputStreamデフォルトの直列化復元モードでは、ユーザオブジェクトへの非transientインスタンス変数は、デシリアライズします。
(2)場合のみ、Userクラスが実装するシリアライズインターフェース、また定義のreadObject(ObjectInputStreamの中)およびwriteObject(ObjectOutputSteamアウト)、次いで、以下のように直列化および非直列化。
ObjectOutputStreamのは、ユーザーオブジェクトのwriteObject(ObjectOutputStreamのうち)直列化のための方法を呼び出します。
ObjectInputStreamのは、ユーザーオブジェクトが逆シリアル化メソッドのreadObject(中のObjectInputStream)を呼び出します。
(3)クラスが実装ExternalnalizableユーザインタフェースとユーザクラスがのreadExternal(れるObjectInputで)とwriteExternalメソッド(するObjectOutputアウト)方式、方法以下のシリアライゼーションおよびデシリアライゼーションを実装する必要がある場合。
プロセスシーケンスのObjectOutputStreamの呼び出し元ユーザーオブジェクトのwriteExternal(のObjectOutput出))。
ObjectInputStreamのは、ユーザオブジェクトのreadExternal(れるObjectInputで)逆シリアル化メソッドを呼び出します。
4、ステップのJDKライブラリシーケンス
それは、このようなファイル出力ストリームとしてターゲット出力ストリームをパッケージングする他の種類の、することができ、オブジェクトを作成するために、出力ストリーム:ステップ:
ObjectOutputStreamのOOS = 新しい ObjectOutputStreamの(新しいたFileOutputStream( "D:\\ object.out"));
ステップ2:経由のwriteObject()メソッドライト対象オブジェクト出力ストリーム
oos.writeObject(新しいユーザー( "xuliugen"、 "123456"、 "男性"));
5、JDKのクラスライブラリ直列化復元ステップ
そのようなファイルの入力ストリームとして入力ストリームの他のタイプのパッケージとすることができる、オブジェクトを作成するために入力ストリーム:手順:
ObjectInputStreamのOIS = 新しい ObjectInputStreamの(新しい FileInputStreamを( "object.out"));
ステップ2:オブジェクト出力ストリームのreadObject()メソッドは、オブジェクトを読み出します。
ユーザのユーザ=(ユーザー)ois.readObject();
説明:逆シリアル化が完了し、正しくデータを読み取るために、シーケンシャル書き込み、読み出し対象のシーケンスフロー入力と一致するオブジェクトから対象オブジェクトへの出力ストリームを保証しなければなりません。
図6に示すように、例示的なシリアライゼーションおよびデシリアライゼーション
より良い次のように簡単な例を挙げ、Javaおよび直列化復元の手順を理解するために:
パブリック クラスSerialDemo { 公共 静的 ボイドメイン(文字列[]引数)がスローにIOException、ClassNotFoundExceptionが{ // 序列化 のFileOutputStream FOS = 新たFileOutputStream( "object.outを" )。 ObjectOutputStreamのOOS = 新しいObjectOutputStreamの(FOS); ユーザーUSER1 = 新しいユーザー( "xuliugen"、 "123456"、 "男性" ); oos.writeObject(USER1)。 oos.flush(); oos.close(); // 反序列化 FileInputStreamのFIS = 新しいですFileInputStreamを( "object.out" ); のObjectInputStream OIS = 新しい新しいObjectInputStreamの(FIS); ユーザuser2が = (ユーザー)ois.readObject(); System.out.printlnは(user2.getUserName() + "" + user2.getPassword() +「」+ user2.getSex()); // デシリアライズされた出力は、次のとおりです。MALE xuliugen 123456 } } パブリック クラスのユーザーを実装、シリアライズ{ プライベート文字列のuserName; プライベート文字列のパスワード; プライベート文字列のセックス; // すべてのパラメータのコンストラクタ、取得、およびsetメソッドが省略されています }
(ウルトラエディットオープンを使用して)次の書類object.out:
注:0000000H-000000c0h行番号上図; 0-fは列を示し、テキストの行の後ろには、このラインを説明進表し、上記バイトコード表現注目コンテンツは、関連情報を制御することができます、ここでは議論しないで表される各文字の意味についての記事を読みます!
私たちは、Javaコードがコンパイルされた後、それぞれの文字が特定の意味を表すの.classファイルが好き。シリアライズとデシリアライズのプロセスが発生し、言った文字の解析のプロセスです!
シリアル化アイコン:
示すには、逆シリアル化:
第三に、関連する注意事項
シリアライズするとき1は、オブジェクトの状態だけではなく、関係なく、メソッドオブジェクトの、保存されます。
図2に示すように、親クラスが実装シリアライズ、自動的にシリアライズサブクラス、明示的な道具シリアライズ。
図3に示すように、オブジェクト参照他のオブジェクト、参照されるオブジェクトをシリアル化するオブジェクトの配列のインスタンス変数。
:4、いないすべてのオブジェクトは、次のような多くの理由のために、なぜしないようにと、シリアライズすることができます
このような送信処理のシーケンスでは、など、ファイルへの書き込み、またはRMIの交通機関として転送されるオブジェクトのオブジェクトは、プライベート、パブリック、およびその他のフィールドを持っているなどのセキュリティ上の理由から、、、、このドメインの民間およびその他の目的のためにあります保護されていません。
送信または保存され、そのようなあなたがシリアライズできるかどうソケット、スレッドクラス、などのリソースの割り当ては、それらへのリソースの再割り当てすることはできません理由は、しかし、達成する必要はありません。
静的データメンバと過渡型として宣言5は、シリアライズすることはできません。オブジェクトのクラス、過渡的な一時的なデータの代表の静的な状態の代表ので。
図6に示すように、バージョン番号がシーケンスに関連付けられた各クラスのserialVersionUIDと呼ばれることも、デシリアライゼーションシリアル化オブジェクトのシーケンス番号は、オブジェクトの送信者と受信者を確認し、ロードされた直列化ランタイムでありますシリアル化されたクラスとの互換性。それは明確な価値を与えるよう。明示的に定義されたserialVersionUIDのは2つの目的があります。
いくつかのケースでは、互換性の配列の所望のクラスの異なるバージョンが、クラスの異なるバージョンが同じserialVersionUIDのを持っていることを確認する必要があります。
いくつかのケースでは、クラスの異なるバージョンは、互換性のシリアライズしたいので、クラスの異なるバージョンが異なるserialVersionUIDのを持っていることを確認する必要はありません。
7、Javaの基礎クラスはすでに、このような文字列、ベクトルなどというように、Serializableインタフェースの多くを達成しています。しかし、Serializableインタフェースを実装していないいくつかあります。
オブジェクトのメンバ変数がオブジェクトである場合は8、そのオブジェクトのデータメンバが保存されます!これは、深いコピーを解決することができます直列化のための重要な理由です。
第四に、逆シリアル化の脆弱性
関連のデシリアライゼーションの脆弱性は、関連する情報にアクセスすることができ、ここでは説明しません。