2011-08-12 1 views

答えて

5

readObject()/writeObject()はプライベートで、ここでは取引があります:あなたのクラスバーがいくつかのクラスFooを拡張している場合、 FooもreadObject()/writeObject()を実装し、BarもreadObject()/writeObject()を実装しています。

Barオブジェクトがシリアライズまたはデシリアライズされると、JVMはFooとBarの両方に対して自動的にreadObject()/writeObject()を呼び出す必要があります。これらのスーパークラスのメソッドを明示的に呼び出す必要はありません)。ただし、これらのメソッドがプライベート以外の場合、メソッドオーバーライドになり、JVMはサブクラスオブジェクトのスーパークラスメソッドを呼び出すことができなくなります。

したがって、プライベートである必要があります。

1

なぜfindbugsがバグだと思うのか分かりませんが、私は2つの理由が考えられます。呼び出し元のコードがクラスの内部構造を把握しているため、readObject publicをカプセル化解除します。また、パブリックにすることで、すべての派生クラスにreadObjectをpublicとして宣言します。したがって、クラスが最終的なものでなければ、シリアライズの契約を変更しています。

私は、findbugsがそのメッセージのほとんどについて論理的根拠を提供できると考えました。これについて何か言いたいことがありますか?

+0

いいえ、それはありません。私がこのメソッドをパブリックにする唯一の理由は、継承しているオブジェクトがそれを使っていないように最終的にすることです。 InvalidObjectExceptionがスローされます。私はシリアライゼーションプロキシを強制的に使用したい。ここでは何のリスクもないと思います。 – JVerstry

1

自分でreadObjectのようなシリアル化メソッドを呼び出す理由はありませんが、他のクラスからはるかに少なくなります。あなたは可能なすべての可視性を最小限に抑える必要があります。

編集:サブクラスが動作を変更できるようにするには、メソッドprotected ...を受け入れてください。

1

このメソッドをパブリックにする唯一の理由は、継承するオブジェクトがそのオブジェクトを参照できないように最終的にすることです。

私はそれを行うにはを試してください。クラスレベルのjavadocに、サブクラスが何をすべきかどうか、あなたが何をすべきでないと思うかを書き留めておいてください。誰かがそのアドバイスを無視してクラスを実装することを選択した場合、その結果に対処することが彼らの問題です。

他の人に特定の方法でサブクラスを強制的に適用しようとすると、にはが必要なユースケースがある可能性があります。わかる。将来の開発者には、自分が望むことを自由に行えるようにし、その結果に対して責任を負わせることが良い考えです。あなたの方法はobjectInputStream.readObject()によって呼び出されるようにするためには

+0

私は一般的にあなたの原則に同意します。しかし、一度シリアライゼーションプロキシを使用し始めると、私はあなたが提供するセキュリティを守り、「パンドラの箱を再オープンしない」と考えています。 – JVerstry

1

、あなたはそれがプライベート宣言する必要があります。

あなたは、あなたのメソッドが呼び出されることはありませんしていない場合は
private void readObject(ObjectInputStream objectInputStream) 

(そこにブレークポイントを置きますこれを証明する)。あなたのコードが正常に動作しているように見えますが、それはデフォルトのシリアル化が使用されているためです。

これをサブクラス化できるように保護したいと思うかもしれませんが、これは必要ありません。シリアライゼーション処理では、具象クラスのreadObjectを呼び出す前に、基本クラスのreadObjectを自動的に呼び出します。私は、ウェブ上で読んだ他の記事に反し

objectInputStream.defaultReadObject(); 

...:これは、具体的なクラスがへの呼び出しを行わない場合にも起こります。同じことがwriteObjectメソッドにも当てはまります。