質問

有効なJavaの防御コピーの例です。根本的な質問の中でシナリオが防御的なコピーを必要とし、クライアントに渡されないようにするコメントを求めるコメントではできません。

public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
}
.

質問:

  1. Dateが自分自身をより一般的にするためのコンストラクタを持っていない場合、自分自身を複製するメカニズムなしでオブジェクトが渡され、そのようなオブジェクトは私たちに属していません。できない方法でそれを変更することはできませんか?

  2. コンストラクタが引数としてタイプパラメータを取った場合、Period(T object)とTとTが変更される可能性があるため、防御コピーが必要です。私たちはT.がどのようなものではありません。この場合は防御的なコピーを行う方法はありませんか?

  3. インターフェースとは、そのサブクラスの一部がDateのようなコンストラクタが渡され、それ自体のオブジェクトを作成し、そのサブクラスの一部がそうするメカニズムはありませんか?

  4. 私たちはどのくらいの深さを防御的にコピーするべきですか?配列をコピーすると言ってくださいが、配列要素は変更できましたか?

役に立ちましたか?

解決

  1. その状態がすべて利用可能な場合は、その状態を抽出して自分で新しいオブジェクトを構築することができます。それ以外の場合は、厄介な反射やシリアル化のトリックを使用して以外はそれについて何もできません。
  2. tがコピーを許可するクラスのインスタンスではない場合は、何もできません。
  3. あなたはそれについて何もできません。
  4. それは依存します。
  5. あなたの質問を読むことによって、あなたがいたるところに「防御コピー」のアドバイスを適用したいようです。あなたはしないでください。ほとんどの場合、可変オブジェクトを使用したコードは元のオブジェクトへの参照、コピーではありません。特に引数として得られるものが抽象クラスまたはインターフェースのインスタンスです。

    変更可能ではない場合は、変更可能な値タイプで、適切に設計されていた場合はそうではないため、デパートのコピーを守ることを余儀なくされています。値の種類の不変性を促進すると、防御的なコピーが不要になります。値ではないタイプの場合は、一般的にコピーを望みませんが、オブジェクトへの参照はありません。

他のヒント

  1. とにかくオブジェクトの状態を変更できない場合は、防御的なコピーは必要ありません。
  2. あなたができる唯一のものはTの可能性のある実装と仮定し、それらを instanceOf で確認することです。
  3. 2と同じです。
  4. あなたの裁量で。配列要素の修正が別の場所でプログラムを破る可能性があると仮定すると、それらをすべてコピーする必要があります。

メソッドに渡すオブジェクトが変更可能な場合に、守備プログラミングが重要です。良い慣習(効果的なJava Bookにも記載されています)はそれらを不変にすることです。

  1. 日付クラスが最終的なものではない場合は、それにラッパークラス、つまり日付のサブクラスを書くことができます。
  2. それは異なります。おそらく、それを複製する必要はありません。
  3. それはあなたを悩ませてはいけません。インターフェイスの実装者は同期の問題を認識する必要があります。一般的に、それらの実装の代わりにインタフェースを渡すことをお勧めします。
  4. 標準のJavaコレクションの場合、守備プログラミングのために使用することを目的とした、unmodifiablelistと非修復のためのjava.util.Collectionsクラスには、たくさんのユーティリティメソッドがあります。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top