シリアライゼーションは、Javaでの永続化に使用されます。シリアル化を使用していくつかのオブジェクトを永続化することは問題ないかもしれません。ただし、オブジェクトが多数ある場合は、ORM、データベースなどの方が適している場合があります。シリアライゼーションは小さなジョブにのみ役立つようです。私は間違っているかもしれません。では、非シリアル化メソッドよりもシリアル化の利点は何ですか?いつ使用し、いつ避けるべきですか?
DZoneの記事 Is Object Serialization Evil? を見て、この質問が頭に浮かびました。
そして、これらは私の質問を引き起こした行です:
Javaとそのセッションオブジェクトを見ると、純粋なオブジェクトシリアライゼーションが使用されています。アプリケーションセッションの存続期間がかなり短いと仮定すると、オブジェクトシリアライゼーションはシンプルで、十分にサポートされていますJavaセッションの概念に組み込まれています。ただし、データの永続性が長期間、おそらく数日または数週間にわたってあり、アプリケーションの新しいリリースについて心配する必要がある場合、シリアライゼーションはすぐに悪になります。Java開発者が知っているように、セッションでもオブジェクトをシリアライズする場合は、1Lだけでなく、実際のシリアライゼーションID(serialVersionUID)が必要です。 Serializableインターフェースを実装する必要があります。ただし、ほとんどの開発者はJava逆シリアル化プロセスの背後にある実際の規則を知りません。オブジェクトが変更された場合、単純なフィールドをオブジェクトに追加するだけでなく、 Javaは、シリアライゼーションIDが変更されていなくても、オブジェクトを正しくデシリアライズできない可能性があります。突然、データを取得できなくなりますが、これは本質的に悪いことです。
さて、これを読んでいる開発者は、この問題が発生するコードを決して記述しないだろうと言うかもしれません。それは本当かもしれませんが、あなたが使用するライブラリや、あなたの会社でもう使われていない他の開発者はどうですか?この問題が発生しないことを保証できますか?それを保証する唯一の方法は、異なるシリアル化方法を使用することです。
シリアル化はほとんどが2つの領域で使用されます。
永続化のプロトタイピング
ほぼすべてのオブジェクトグラフをすばやくシリアライズ可能にすることができます。概念実証や迅速でダーティなアプリケーションの場合、これは実際のORMレイヤーや他の永続化システムをセットアップするよりも高速です。
ほとんど任意のオブジェクトの短期ストレージ:
たとえば、アプリケーションサーバーは、シリアル化を使用してセッション情報を保持する傾向があります。これには、セッション内の値が(そのシリアライズ可能である限り)ほとんどすべてのタイプであるという利点があります。
他のほとんどすべての用途では、あなた(および記事)が言及している欠点が大きすぎます。正確な形式を安定させるのは難しいです。クラスを変更すると、シリアル化されたデータが簡単に読み取れなくなり、Java以外のコードでデータを読み書きすることはほぼ不可能になります。不可能(または少なくとも必要以上に難しい)。
JAXBと同様のテクノロジーは、いくつかの問題を軽減しながら、同様の低コストで同様の機能を提供します。
オブジェクトのシリアル化を使用して、本番環境で予期しないエラーが発生した場合の事後分析を可能にします。計算への入力は、データファイルにシリアル化されます。エラーが報告された場合、単純なプログラムで入力を再読み込みし、デバッガーを接続して計算を再実行できます。または、グルーヴィーなシェルを使用してオブジェクトをリロードし、必要に応じて変更することもできます。
また、シリアル化を使用してJavaオブジェクトをHTTP経由でWebサービスに渡します。テキストとの間でシリアル化するよりもはるかに簡単です。欠点は、クライアントとサーバーのインストールを一緒にデプロイする必要があることですが、両端を制御しているので問題です。
非シリアル化メソッドよりもシリアル化の利点は何ですか?
Javaシリアライゼーションにはいくつかの利点があります。
システムに組み込まれています:サードパーティのツール、ライブラリ、構成に依存する必要はありません。
比較的理解しやすい、少なくとも最初は。
すべての開発者はそれを知っています(またはすべきです)。 Java開発者が承認するか否かに関係なく、開発者はJavaオブジェクトのシリアライズに慣れている可能性があります。
そしてもちろん、欠点もあります:
標準を回避しますJavaフロー。メモリを割り当てますが、コンストラクターを呼び出さないため、一時的なフィールドは初期化されません。フィールドはソース順ではなくアルファベット順に初期化されます。
それほど効率的ではありませんスペースに関しては、恐ろしいものでもありません。結果を圧縮することができます。
予防策を講じない限り脆弱オブジェクトが変更されたとき。そしてそれでも。
いつ使用し、いつ避けるべきですか?
使用時期:
展開サイズが重要です。システムに組み込まれているため、余分なバイトは0です。
すべての俳優は互換性のあるバージョンを使用します。
長期保存は問題ではありません。
回避する場合:
シリアル化とORM /データベースは異なりますが、一部重複しています。
シリアル化されたオブジェクトは、永続化されたオブジェクトを「解凍」してデータを再入力するために必要なすべての情報を表します。 ORMとデータベースは、データをデータベースに永続化します。クラスには、ORMによってデータベースに格納されない情報のフィールド(計算フィールドなど)を含めることができます。
さらに、シリアル化とORMは異なる問題を解決しています。直列化は、オブジェクトグラフをストリーム(メモリ、ファイルシステムなど)に永続化する問題を解決します。 ORMは、検索や遅延読み込みなどの機能を提供するだけでなく、情報のデータベース列へのマッピング、オブジェクトの取得とインスタンス化も処理します。
ORMは、大量のデータを処理している場合や、レポート、検索/クエリ、倉庫保管など、データベースが得意なものを必要とする状況でデータベースにデータを永続化する場合に使用します。データ構造の表現をディスクに保存する場合は、シリアル化を使用します。
「Javaシリアライゼーションを使用する場合」および「Javaシリアライゼーションを使用しない場合」への短い回答
Java serialization if
他のすべての状況では、「バイナリJavaシリアライゼーション)は不適切です
代替案
シリアライゼーションが実際に使用されることはほとんどありません。
すでに述べたように、シリアル化の最も一般的な使用例は、オブジェクトをブロブとしてセッションデータベースに格納することです。これは2つの理由でうまく機能します。セッションは短命である傾向があり、セッションデータベースは任意のオブジェクトをリレーショナルモデルにマッピングする方法を知らないためです。
長期間保持する必要があるデータ(Amazonショッピングカートなど)の場合、そのデータをデータベースに保存することをお勧めします。
セッション持続性メカニズムにより、アクティブなセッションを持つユーザーが同じサーバーに確実に戻されます。セッションデータベースは、サーバーに障害が発生し、ユーザーが新しいサーバーにリダイレクトされた場合にのみアクセスされます。新しいサーバーはアクティブなセッションを検出しますが、それをメモリ内で見つけられないため、ユーザーにシームレスなエクスペリエンスを提供するためにセッションデータベースから取得しようとします。
このアプローチには2つの問題があります。
まず、セッションデータベースへのセッションデータのフラッシュは、処理が遅くなります。多くの場合、セッションデータをフラッシュするとパフォーマンスが低下し、ほとんどのサーバーは30秒ごと、または1分ごと、またはそれ以上の頻度でフラッシュするように構成されています。この「シームレスな」フェイルオーバーソリューションは100%効果的ではありません。
第二に、私の経験では、ほとんどのクライアントが、サーバーに障害が発生するまれな場合に、ユーザーにログインして再試行するように求めるエラーメッセージをスローすることに同意しています。この場合、セッションデータベースを完全にオフにして、パフォーマンスを向上させます。
シリアル化のもう1つの用途は、サーバーとクライアントの相互作用にオブジェクトグラフのシリアル化と圧縮を使用するFlexなどのフレームワークを使用して、応答時間を短縮することです。
他の人が指摘したように、シリアライゼーションを採用する創造的で有用な理由はいくつかありますが、実際にはまれです。
歴史的に、シリアライゼーションを正しく実装して信頼性を高めることは困難であり、使用を少数のケースに制限しています。ほとんどの開発者はオブジェクト自体をシリアル化することは決してありませんが、舞台裏でそれを行うフレームワークに依存する場合があります。