Java には、フェイルファストおよびフェイルセーフの反復設計があることを知っています。
なぜ基本的にこれらが必要なのか知りたいです。この分離の根本的な理由はありますか? . この設計の利点は何ですか?.
コレクションの反復以外に、Java はこの設計をどこでも踏襲していますか?
ありがとう
Java には、フェイルファストおよびフェイルセーフの反復設計があることを知っています。
なぜ基本的にこれらが必要なのか知りたいです。この分離の根本的な理由はありますか? . この設計の利点は何ですか?.
コレクションの反復以外に、Java はこの設計をどこでも踏襲していますか?
ありがとう
プログラマーにとって、コードにバグが含まれている場合、コードができるだけ早く失敗しようとすることは便利です。コンパイル時が最適ですが、それが不可能な場合もあります。
そのため、エラーを早期に検出できます。そうしないと、エラーが検出されずに何年もの間ソフトウェアに含まれ、誰もバグに気付かない可能性があります。
そのため、エラーやバグをできるだけ早く検出することが目標です。したがって、パラメーターを受け入れるメソッドは、パラメーターが許容範囲内にあるかどうかをすぐに確認する必要があります。これは、フェイルファーストへの一歩となります。
これらの設計目標は、イテレーションだけでなく、どこにでもあります。単純に、それが良いアイデアだからです。しかし、使いやすさやその他の要素とのトレードオフが必要な場合もあります。
例として、Set実装nullは多くのバグの原因となる値を許可します。新しい Java 9 コレクションはこれを許可せず、そのようなものを追加しようとするとすぐに例外をスローします。これはfail-fastです。
あなたのイテレータも良い例です。コレクションの反復中にコレクションを変更することはできません。主な理由は、エラーの原因になりやすいためです。したがって、彼らはConcurrentModificationException.
反復の特殊なケースでは、物事がどのように機能するかを誰かが指定する必要があります。反復中に新しい要素が追加または削除された場合、反復はどのように動作する必要がありますか? 反復に含める/削除する必要がありますか、それとも無視する必要がありますか?
例として、反復および操作するListIteratorための非常に明確に定義されたオプションを提供します。Listそこでは、イテレータが現在あるオブジェクトを操作することしか許可されていません。これにより、オブジェクトが明確に定義されます。
反対側には、ConcurrentHashMap. それらはそのような例外をスローせず、変更を許可します。ただし、元のコレクションのコピーに取り組んでおり、「方法」の質問も解決しています。そのため、マップ上の変更は反復子に反映されず、反復子は反復中の変更を完全に無視します。これにはコストがかかります。反復するたびに完全なコピーを作成する必要があります。
個人的には、これらのフェイルセーフバリアントはオプションではありません。私はフェイルファストバリアントを使用し、操作したいものを記憶します。反復が終了したら、記憶した操作を実行します。
これはプログラマーにとって書き心地が悪いですが、fail-fastの利点を得ることができます。これが、使いやすさとのトレードオフで私が意味したことです。