Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Effective Java 輪読会 項目77-78

660 views

Published on

Published in: Technology
  • Login to see the comments

  • Be the first to like this

Effective Java 輪読会 項目77-78

  1. 1. Effective Java 輪読会 2014/03/19 開発部田中
  2. 2. 項目77 インスタンス制御に対しては、readResolve よりenum 型を選ぶ
  3. 3. readResolveによるインスタンス制御 • シングルトンをシリアライズする場合の伝 統的な方法 o 自身の持つシングルトンインスタンスを返すような readResolveメソッドを定義することで、デシリア ライズによって生成されたインスタンスは破棄し、 常にメモリ上に存在するインスタンスの参照を返す。
  4. 4. インスタンス制御する場合のtransient • readResolveによって常にメモリ上のインス タンスを返すのなら、シングルトンクラス のインスタンスフィールドをシリアライズ の対象にする必要はない。 → transient修飾子を付与する
  5. 5. 攻撃に備えてtransientを付与する • むしろreadResolveによってシリアライズさ れるクラスのインスタンスフィールドは transientにすべき • readResolveが呼ばれる前に、デシリアライ ズによって生成されたインスタンスの参照 を「盗む」ことができてしまう。
  6. 6. 実際に参照を盗んでみる
  7. 7. enumを使う • readResolveによるインスタンス制御は、廃 れてはいないが、十分な注意が必要 • そこで、enumを使えば、シングルトン特性 をJVMが保証してくれる • enumが使えない場合もある
  8. 8. readResolveのアクセス可能性 • デシリアライズは、クラス階層の上から行 われる。 • スーパークラスのインスタンスが生成され てClassCastExceptionが発生しないように 気をつける
  9. 9. まとめ • シリアライズのインスタンス制御には、可 能な限りenumを使う • readResolveメソッドによるインスタンス制 御の場合は、インスタンスフィールドがプ リミティブ型か、transientであることを確認 する
  10. 10. 項目78 シリアライズされたインスタンスの代わりに、 シリアライズ・プロキシを検討する ・シリアライズ・プロキシ・パターンとは ・writeReplace とreadResolve
  11. 11. なぜ使うか • ネストしたクラスに、エンクロージングク ラスの論理的状態を表現する • シリアライズ・プロキシから元のクラスの インスタンスに復元する際に、元のクラス のコンストラクタを使用できる • 言語機能によってデシリアライズを制御できる
  12. 12. ポイント1: writeReplace • エンクロージングクラスをシリアライズ・ プロキシへ変換する(シリアライズ・プロ キシクラスの形式でシリアライズする)
  13. 13. ポイント2: readResolve • シリアライズ・プロキシクラスに readResolveを実装する • デシリアライズの際にシリアライズ・プロ キシをエンクロージングクラスのインスタ ンスにエンクロージングクラスのコンスタ ラクタを使って変換する。
  14. 14. readResolveの柔軟性 • readResolveではpublicのAPIのみを使用して インスタンスを生成できる • staticファクトリーメソッドも使える • 実際にどのクラスのインスタンスを返すか 制御できる。 • ex. EnumSet
  15. 15. まとめ • finalクラスについて、readObjectや writeObjectを書く必要がある場合には、シ リアライズ・プロキシ・パターンを検討す る • クラスの不変式をシリアライズするための 簡単・確実な方法

×