Javaシリアル化-長所と短所、使用または回避?[閉まっている]


20

シリアル化は、Javaの永続化に使用されます。シリアル化を使用していくつかのオブジェクトを永続化してもかまいません。ただし、多数のオブジェクトの場合、ORM、データベースなどの方が適している場合があります。シリアル化は、小さなジョブにのみ役立つようです。私は間違っているかもしれません。それでは、非シリアル化方法よりもシリアル化の利点は何ですか?いつそれを使用し、いつそれを避けるべきですか?

この質問は、DZoneの記事Is Object Serialization Evil?を見て思い浮かびました

そして、これらは私の質問を引き起こした行です:

Javaとそのセッションオブジェクトを見ると、純粋なオブジェクトのシリアル化が使用されます。アプリケーションセッションの存続期間がかなり短い(最大で数時間)と仮定すると、オブジェクトのシリアル化は単純であり、十分にサポートされ、セッションのJavaコンセプトに組み込まれています。ただし、データの永続性が長期間(場合によっては数日または数週間)にわたり、アプリケーションの新しいリリースを心配する必要がある場合、シリアル化はすぐに悪になります。優れたJava開発者が知っているように、セッションでもオブジェクトをシリアル化する場合は、1Lだけでなく実際のシリアル化ID(serialVersionUID)が必要であり、Serializableインターフェイスを実装する必要があります。ただし、ほとんどの開発者は、Javaの逆シリアル化プロセスの背後にある実際のルールを知りません。オブジェクトが変更された場合、オブジェクトに単純なフィールドを追加するだけでなく、シリアライゼーションIDが変更されていなくても、Javaがオブジェクトを正しくデシリアライズできない可能性があります。突然、データを取得できなくなります。これは本質的に悪いことです。

さて、これを読んでいる開発者は、この問題のあるコードを決して書かないと言うかもしれません。それは本当かもしれませんが、あなたが使用しているライブラリや、あなたの会社に雇用されなくなった他の開発者はどうでしょうか?この問題が発生しないことを保証できますか?それを保証する唯一の方法は、異なるシリアル化方法を使用することです。


参照された記事で具体的に何があなたの質問を引き起こしたかについて少し拡大していただけますか?
ブヨ

@gnat-質問に行を追加しました。
スカイスクレーパー

「単なる1L」ではない部分は正しくありません。
user207421

回答:


15

シリアル化は、に次の2つの領域で使用されます。

  • 永続性のプロトタイピング

    ほぼすべてのオブジェクトグラフをすばやく直列化可能にすることができます。迅速な概念実証または迅速でダーティなアプリケーションの場合、これは実際のORMレイヤーまたは他の永続性システムをセットアップするよりも高速です。

  • ほとんど任意のオブジェクトの短期保存:

    たとえば、アプリケーションサーバーは、シリアル化を使用してセッション情報を保持する傾向があります。これには、セッション内の値がほぼすべての型になり得るという利点があります(そのシリアル化可能な限り)。

他のほとんどすべての用途では、あなた(および記事)が言及する欠点は大きすぎます:正確な形式は安定性を保つのが難しく、クラスの変更はシリアル化されたデータを簡単に読み取れないようにし、非Javaコードでのデータの読み取り/書き込みはほとんどありません不可能(または少なくとも必要以上に難しい)。

JAXBおよび同様のテクノロジーは、いくつかの問題を軽減しながら、同様の低コストで同様の機能を提供します。


JAXBを「低コスト」とは呼びません。スキーマを作成する必要があります。
ケビンクライン

3
@kevincline:JAXBのスキーマは必要ありません。完全にオプションです(必要に応じて、クラスからスキーマを生成することもできます)。また、何らかの理由でJAXBが役に立たない場合は、XML Beansが同様に機能するなど、多くの代替手段があります。
ヨアヒムザウアー

12

オブジェクトのシリアル化を使用して、本番環境で予期しないエラーが発生した場合の事後分析を可能にします。計算への入力は、データファイルにシリアル化されます。エラーが報告された場合、単純なプログラムで入力を再読み込みし、デバッガーを接続して計算を再実行できます。または、Groovyシェルを使用してオブジェクトをリロードし、必要に応じて変更できます。

また、シリアル化を使用して、JavaオブジェクトをHTTP経由でWebサービスに渡します。テキストとのシリアル化よりもはるかに簡単です。欠点は、クライアントとサーバーのインストールを一緒に展開する必要があることですが、両端を制御するため問題ありません。


3
それは興味深いユースケースです!「複雑な」システムを呼び出すには小さすぎますが、ほとんどの欠点は当てはまりません。
ヨアヒムザウアー

POIを使用して、見やすくするためにJavaオブジェクトからスプレッドシートを作成する事後分析ツールを作成しました。これにより、ログファイルの検査に何時間も費やされました。
ケビンクライン

7

非シリアル化方法よりもシリアル化の利点は何ですか?

Javaシリアル化にはいくつかの利点があります。

  • システムに組み込まれている:サードパーティのツール、ライブラリ、または構成に依存する必要はありません。

  • 少なくとも最初は理解するのが比較的簡単です。

  • すべての開発者はそれを知っています(またはそうすべきです)。Java開発者が承認するかどうかに関係なく、Javaオブジェクトのシリアル化に精通している可能性があります。

そして、もちろん、欠点もあります:

  • 標準のJavaフローを回避します。 メモリを割り当てますが、コンストラクターを呼び出さないため、一時フィールドは初期化されません。フィールドはソース順ではなくアルファベット順で初期化されます。

  • スペースの面ではそれほど効率的ではありませんが、恐ろしいことでもありません。結果を圧縮することもできます。

  • オブジェクトが変更されたときに予防措置を講じない限り、もろい。そしてそれでも。

いつそれを使用し、いつそれを避けるべきですか?

使用する場合

  • 展開サイズが重要です。システムに組み込まれているため、余分なバイトはありません。

  • すべてのアクターは互換バージョンを使用します。

  • 長期保管は問題ではありません。

次の場合は避けてください

  • 上記のいずれも適用されません。

3

シリアル化とORM /データベースは異なるものですが、一部重複しています。

シリアル化されたオブジェクトは、永続化されたオブジェクトを「解凍」してそのデータを再生成するために必要なすべての情報を表します。ORMとデータベースは、データをデータベースに永続化します。クラスには、ORMによってデータベースに保存されない情報のフィールド(計算フィールドなど)を含めることができます。

さらに、シリアル化とORMはさまざまな問題を解決しています。シリアル化は、オブジェクトグラフをストリーム(メモリ、ファイルシステムなど)に永続化する問題を解決します。ORMは、情報の一部をデータベース列にマッピングし、オブジェクトの取得とインスタンス化を処理するほか、検索や遅延読み込みなどの機能を提供します。

大量のデータを処理している場合や、レポート、検索/クエリ、ウェアハウジングなど、データベースが得意なことを必要とする状況でデータをデータベースに保持する場合は、ORMを使用します。データ構造の表現をディスクに保存する場合は、シリアル化を使用します。


0

シリアル化が実際に使用されることはほとんどありません。

既に述べたように、シリアル化の最も一般的な使用例は、セッションデータベースにオブジェクトをBLOBとして保存することです。これは2つの理由でうまく機能します。セッションは短命である傾向があり、セッションデータベースは任意のオブジェクトをリレーショナルモデルにマッピングする方法の知識がありません。

長期間保持する必要があるデータ(Amazonショッピングカートなど)のベストプラクティスは、そのデータをデータベースに保存することです。

セッション永続化メカニズムにより、アクティブなセッションを持つユーザーが同じサーバーに確実に返されます。セッションデータベースにアクセスするのは、サーバーに障害が発生し、ユーザーが新しいサーバーにリダイレクトされた場合のみです。新しいサーバーはアクティブなセッションを検出しますが、メモリ内でそれを見つけられないため、ユーザーにシームレスなエクスペリエンスを提供するためにセッションデータベースからセッションを取得しようとします。

このアプローチには2つの問題があります。

まず、セッションデータをセッションデータベースにフラッシュする処理は時間がかかります。セッションデータをフラッシュするとパフォーマンスが低下することが多く、ほとんどのサーバーは30秒ごと、1分ごと、またはそれ以上の時間でフラッシュするように構成されています。この「シームレス」フェイルオーバーソリューションは、100%効果的ではありません。

第二に、私の経験では、ほとんどのクライアントは、サーバーに障害が発生するまれな場合にユーザーにログインして再試行するよう求めるエラーメッセージを表示することに同意します。この場合、セッションデータベースを完全にオフにして、パフォーマンスを向上させます。

シリアル化のもう1つの用途は、サーバーとクライアントの対話にオブジェクトグラフのシリアル化と圧縮を使用するFlexなどのフレームワークを使用して、応答時間を短縮することです。

他の人が指摘したように、シリアル化を採用するいくつかの創造的で有用な理由がありますが、これらは実際にはまれです。

歴史的に、シリアル化は正しく実装するのが難しく、信頼性が低いため、使用を少数のケースに制限しています。ほとんどの開発者はオブジェクト自体をシリアル化することはありませんが、舞台裏でそれを行うフレームワークに依存する場合があります。


2
「シリアル化は実際にはほとんど使用されません。」-シリアル化は、REST Webサービスの世界でよく呼ばれます。ほとんどの場合、1つは文字列や整数などを処理するだけですが、実際のことであり、より複雑なオブジェクトはそれを認識する必要があります。めったに使用されないということは、それを頻繁に使用するドメインの大部分を無視します。

0

「Javaシリアル化を使用する場合」および「Javaシリアル化を回避する場合」に対する簡単な回答

Javaシリアル化を使用する場合

  • コーディングはほとんど必要ありません
  • バイナリデータが人間が読めなくてもかまいません
  • シリアル化されたデータの検索は必要ありません(データベースのようなクエリは不可能です)
  • どちらか
    • シリアル化されたデータ構造が変更されない、または
    • 格納されたシリアル化されたデータが「データ構造の変更」後に読み取れないかどうかは関係ありません(つまり、Webアプリのセッションデータ)

他のすべての状況では、「バイナリJavaシリアル化」が悪い

代替案

  • XMLシリアル化
  • nosqlデータベース
  • ORMを使用したリレーショナルデータベース
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.