いつSerializableインターフェースを実装する必要がありますか?


153
public class Contact implements Serializable {
    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}
  1. いつSerializableインターフェイスを実装する必要がありますか?
  2. なぜそれを行うのですか?
  3. 利点やセキュリティはありますか?

1
ここで受け入れられた回答は、セキュリティの欠点に対処していないため、不完全で誤解を招くものです。参照してください効果的なJavaの項目86:細心の注意を持つ直列化を実装します。 ここでシリアル化を使用しないと言うレイドワルドの答えは正しいものです。
Nathan Hughes

回答:


157
  1. 以下からのすべてについて、この「シリアライズ」のことは何?

    オブジェクトまたはオブジェクトのグループを取得し、それらをディスクに配置するか、ワイヤーまたはワイヤレスのトランスポートメカニズムを介して送信します。その後、おそらく別のコンピューター上で、逆のプロセスで元のオブジェクトを復活させます。基本的なメカニズムは、オブジェクトをビットの1次元ストリームに平坦化し、そのビットストリームを元のオブジェクトに戻すことです。

    スタートレックのトランスポーターのように、複雑なものを取り、それを1と0のフラットシーケンスに変換し、次に1と0のシーケンスを(おそらく別の場所で、おそらく別の時間に)取り、元の複雑な「何か。"

    そのSerializableため、オブジェクトのコピーを保存する必要がある場合にインターフェースを実装し、同じシステム上またはネットワーク経由で実行される別のプロセスに送信します。

  2. オブジェクトを保存または送信するため。

  3. オブジェクトの保存と送信が簡単になります。セキュリティとは何の関係もありません。


4
すべてのドメインモデルにseriablizbleインターフェイスを実装するのがベストプラクティスですか?
theJava

8
@theJavaこれはベストプラクティスの問題ではありません。一連のバイトが必要かどうかの問題です。
moinudin 2010

5
JSONを使用する場合、このインターフェイスを実装する必要はなく、単にその文字列を送信できます。そのため、JSONを使用できるときにこのインターフェイスを使用する理由がわかりません。
Yonatan Nir

1
@YonatanNir MsgPack、Avro、Thrift、またはProtobufの方がIO転送に適しているのに、なぜJSONを使用するのかわかりません。
OneCricketeer

1
@YonatanNir厳密に定義されたスキーマの方が優れています。そして、JSONは人間が読めるようにすることを目的としていますが、バイナリエンコード形式は
ネットワーク

48
  1. Serializableクラスのインスタンスを一連のバイトに変換できるようにする場合、またはSerializableオブジェクトがクラスのインスタンスを参照する可能性があると思われる場合は、インターフェイスを実装します。

  2. Serializable クラスは、それらのインスタンスを永続化したり、ネットワーク経由で送信したりする場合に役立ちます。

  3. Serializableクラスのインスタンスは簡単に送信できます。ただし、シリアライゼーションにはセキュリティ上の影響があります。Joshua BlochのEffective Javaを読んでください。


32

この質問への答えは、おそらく驚くべきことに、 決して、またはより現実的には、レガシーコードとの相互運用性を強要された場合限られます。これは、Joshua BlochによるEffective Java、3rd Editionの推奨事項です。

作成する新しいシステムでJavaシリアル化を使用する理由はありません

OracleのチーフアーキテクトであるMark Reinholdは、現在のJavaシリアライゼーションメカニズムを削除することが長期的な目標であると記録に残しています。


Javaシリアライゼーションに欠陥がある理由

Javaは言語の一部として、Serializableインターフェースを使用してオプトインできるシリアライゼーションスキームを提供します。ただし、このスキームにはいくつかの扱いにくい欠陥があり、Java言語設計者は失敗した実験として扱う必要があります。

  • これは、基本的に1はについて話すことができることをふりオブジェクトの直列化された形式。しかし、シリアル化スキームは無限にあり、その結果、シリアル化された形式は無限に多くなります。1つのスキームを課すことにより、スキームを変更する方法がなければ、アプリケーションはそれらに最も適したスキームを使用できません。
  • これは、オブジェクトを構築する追加の手段として実装され、コンストラクターまたはファクトリーメソッドが実行する前提条件チェックをバイパスします。トリッキーでエラーが発生しやすく、追加の逆シリアル化コードをテストするのが難しい場合を除いて、コードにセキュリティギャップがあります。
  • シリアル化されたフォームの異なるバージョンの相互運用性をテストすることは非常に困難です。
  • 不変オブジェクトの処理は面倒です。

代わりに何をすべきか

代わりに、明示的に制御できるシリアル化スキームを使用してください。プロトコルバッファ、JSON、XML、独自のカスタムスキームなど。


2
そのレベルではあまり専門家ではありませんが、あなたはポイントを持っていると感じています。
Nightfury

1
それが最良の答えだと思います!
jjanczur
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.