Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

Effective Java 輪読会 項目76

804 vues

Publié le

Effective Java 輪読会 項目76

Publié dans : Technologie
  • Login to see the comments

  • Soyez le premier à aimer ceci

Effective Java 輪読会 項目76

  1. 1. Effective Java 輪読会第9回 (項目76) 2014/3/12 開発部野口
  2. 2. 項目76 防御的にreadObject を書く
  3. 3. readObject は もう1 つのpublic コンストラクタ  よって、以下の指針がreadObject にも当ては まる  項目38 パラメータの正当性を検査する  項目39 必要な場合には、防御的にコピーする
  4. 4. パラメータの正当性を検査する  入力バイトストリームを直接編集することによって、任 意の値を持ったオブジェクトを生成できてしまう! (pp.292)  ので、defaultReadObject の呼び出し後に正当性検査を 行うreadObject メソッドを提供する private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { ↓ s.defaultReadObject(); // 不変式が満足されているかどうかを検査する if (start.compareTo(end) > 0) throw new InvalidObjectException(start + " after " + end); }
  5. 5. 不正オブジェクト参照  シリアライズしたバイト列のあとに特定のバ イト列を追加し、そのバイト列をreadObject でディシリアライズすることによって、 Period オブジェクト内部のDate フィールド への参照を取得することができる!(pp.293- 294)  (この辺詳しくは、「Java オブジェクト直列化 仕様」を読みましょう)
  6. 6. 不正オブジェクト参照への対処: 防御的にコピーする private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException { s.defaultReadObject(); // 可変要素を防御的にコピーする start = new Date(start.getTime()); end = new Date(end.getTime()); // 不変式が満足されているかを検査する if (start.compareTo(end) > 0) throw new InvalidObjectException(start + " after " + end); }
  7. 7. 防御的コピーについての諸注意  正当性検査は防御的コピーの後に行う  先に行うと、TOCTOU 攻撃にさらされる(参照: 項 目39)  clone メソッドを使用しない  clone は、不正なサブクラスを返すことができる(参 照: 項目39)  (残念ながら)フィールドをfinal にすることは できない  防御的コピーの代わりにwriteUnshared / readUnshared を使用しない(参照: 項目77 の問 題が生じる)
  8. 8. デフォルトのreadObject を 使用できるか?  「オブジェクト内のtransient ではない個々の フィールドに対する値をパラメータとして受 け取り、それらの値を正当性検査をすること なくフィールドに保存するpublic のコンスト ラクタ」を追加することを快く感じるか  感じなければ、明示的なreadObject メソッドを 提供し、コンストラクタと同等の正当性検査と防 御的コピーを行う  あるいは、シリアライズ・プロキシ・パターンを用い る(参照: 項目78)
  9. 9. readObject では、オーバーライド可能 なメソッドを呼び出さない  「項目17 継承のために設計および文書化する、 でなければ継承を禁止する」で示されたもの と同様の問題があります  サブクラスの状態がディシリアライズされる前に 実行される
  10. 10. まとめ  private でなければならないオブジェクト参照 フィールドを持つクラスでは、それらを防御的に コピーする  (防御的コピーの後に)不変式を検査し、失敗し た場合はInvalidObjectException をスローする  ディシリアライズされた後にオブジェクトグラフ 全体の正当性を検査したければ、 ObjectInputValidation インタフェースを使用する  (この辺詳しくは、「Java オブジェクト直列化仕 様」を読みましょう)  クラス内のオーバーライド可能なメソッドを呼び 出さない

×