アサーションをいつ使用するか、いつ例外を使用するか
質問
ほとんどの場合、コード内の条件をチェックするために例外を使用しますが、アサーションを使用するのに適切なタイミングはいつなのか疑問に思います。
例えば、
Group group=null;
try{
group = service().getGroup("abc");
}catch(Exception e){
//I dont log error because I know whenever error occur mean group not found
}
if(group !=null)
{
//do something
}
アサーションがここにどのように適合するかを示していただけますか?アサーションを使用する必要がありますか?
製品コードではアサーションをまったく使用せず、単体テストでのみアサーションを確認しているようです。ほとんどの場合、例外を使用して上記のようなチェックを実行できることはわかっていますが、それを「専門的に」行う適切な方法を知りたいです。
解決
アサーションは、決して起こらないはずです何かを確認するために使用する必要があります。
は、例えば、関数は0で割るかもしれないので、例外が使用されるべきであるが、アサーションは、ハードドライブが突然消えることを確認するために使用することができます。
アサーションが実行してからプログラムを停止しますが、例外は、プログラムが実行を続ける聞かせます。
if(group != null)
は単なる条件である、主張されない。 注
他のヒント
私の考えでは(リストは不完全かもしれませんし、長すぎてコメントに収まりません)、私は次のように言います。
- パブリックまたはプロテクトされたメソッドおよびコンストラクターに渡されるパラメーターをチェックするときに例外を使用する
- ユーザーと対話する場合、またはクライアント コードが例外的な状況から回復することが期待される場合は、例外を使用します。
- 例外を使用して、発生する可能性のある問題に対処する
- プライベート/内部コードの事前条件、事後条件、不変条件をチェックするときにアサーションを使用する
- アサーションを使用して自分自身または開発者チームにフィードバックを提供します
- 発生する可能性が非常に低いことをチェックする場合はアサーションを使用してください。そうでない場合は、アプリケーションに重大な欠陥があることを意味します。
- アサーションを使用して、(おそらく)真実であると知っていることを述べます
言い換えれば、例外はアプリケーションの堅牢性に対処し、アサーションはアプリケーションの正確さに対処します。
アサーションは低コストで作成できるように設計されており、ほぼどこでも使用できます。私は次の経験則を使用しています。アサーション ステートメントが愚かに見えるほど、そのステートメントには価値があり、より多くの情報が埋め込まれています。正しく動作しないプログラムをデバッグするときは、経験に基づいて、より明らかな失敗の可能性を必ず確認するでしょう。次に、起こり得ない問題がないか確認します。このような場合に、アサーションが非常に役立ち、時間を節約できます。
アサーションはパラメータを使用して実行時に無効にできることに注意してください。 デフォルトでは無効になっています, したがって、デバッグ目的以外では当てにしないでください。
また、読んでください。 Assert に関する Oracle の記事 アサートを使用する、または使用しない、その他のケースを参照してください。
原則として:
- アサーションは、誰かがオフにしてもまったく問題にならない内部整合性チェックに使用します。(注意してください。
java
コマンドはデフォルトですべてのアサーションをオフにします)。 - オフにしてはいけないものをチェックするには、定期的なテストを使用します。これ 含まれています バグによる潜在的な損害や、ユーザーや外部サービスによって提供される検証データ/リクエストなどを防ぐ防御チェック。
あなたの質問の次のコードは悪いスタイルです そして 潜在的にバグがある
try {
group = service().getGroup("abc");
} catch (Exception e) {
//i dont log error because i know whenever error occur mean group not found
}
問題は、例外がグループが見つからなかったことを意味することがわからないことです。また、 service()
呼び出しが例外をスローした、または例外が返されたこと null
それが原因で NullPointerException
.
「予期される」例外をキャッチした場合は、次のようにキャッチする必要があります。 のみ あなたが期待している例外。捕まえることで java.lang.Exception
(特にログを記録しないことにより) 問題の診断/デバッグが困難になり、アプリがより多くの損害を与える可能性があります。
このドキュメントによると http://docs.oracle.com/javase/6/docs/technotes/guides/ language/assert.html#design-faq-general, "assert ステートメントは、非パブリックの事前条件、事後条件、およびクラスの不変条件のチェックに適しています。パブリックな前提条件のチェックは、IllegalArgumentException や IllegalStateException などの特定の文書化された例外を引き起こすメソッド内のチェックによって引き続き実行される必要があります。
事前条件、事後条件、クラス不変式について詳しく知りたい場合は、このドキュメントを確認してください。 http://docs.oracle.com/javase/6/docs/technotes/guides/ language/assert.html#usage-conditions. 。アサーションの使用例も含まれています。
まあ、Microsoftの裏には、勧告は、すべてのAPIでの例外をスローするようにしたあなたは、公的に利用可能にし、使用することは、あなたが内部のコードについて作る仮定のすべての種類にアサート。それは緩い定義のビットだが、私はそれがラインを描画するために、各開発者までだと思う。
例外の使用については、名前が言うように、その使用方法は、あなたが上記の提示のコードのために例外そうでなければなりません何のサービスが存在しない場合、getGroup
コールがnull
を返す必要があります。ネットワークリンクがダウンまたはそのような何かあれば例外にのみ発生する必要があります。
私は結論は、それは例外対アサートの境界を定義するために、各アプリケーションの開発チームまで左ビットだということだと思います。
あなたはそれがのいずれかののエラーをキャッチします持っているように、ヌルのテストが唯一のtry / catchのに対し、問題を引き起こしてnullをキャッチします。
は大まかに言えば、のtry / catchは安全ですが、わずかに遅い、とあなたが発生する可能性があり、エラーのすべての種類をキャッチしていることに注意する必要があります。私は使用のtry / catch言うよう - 。一日のgetGroupコードが変更される可能性があり、そしてあなただけでは大きなネットが必要になる場合があります。
あなたはその使用しながら、心の中で、この単純な違いを使用することができます。例外は、アサーションが前提条件が検証されているかどうか確認するために、実行時にデバッグ目的のために主に使用されながら期待と呼ばれる予期しないエラーをチェックし、未チェックのエラーをチェックするために使用されます。
正直に言いますが、あなたの質問には少し混乱しています。アサーション条件が満たされない場合、例外がスローされます。紛らわしいことに、これはこう呼ばれます アサーションエラー. 。(例) のようにチェックが入っていないことに注意してください。 IllegalArgumentException これは非常によく似た状況でスローされます。
したがって、Javaでアサーションを使用する
- 条件/スローブロックを記述するより簡潔な手段です
- JVM パラメーターを使用してこれらのチェックをオン/オフにすることができます。通常、実行時のパフォーマンスに影響を与えたり、同様のペナルティが発生したりしない限り、これらのチェックは常にオンのままにします。
次のリンクにあるSunのマニュアルのセクション6.1.2(その他のエラーコード対アサーション)を参照してください。
http://www.oracle.com/technetwork/articles/javase/ javapch06.pdfする
この文書では、私はアサーションを使用するときに見た中で最高のアドバイスを提供します。文書からの引用:
「親指の良いルールは、あなたが期待していないことを条件または状態、あなたがアンアサーションに対処する最も簡単な方法です。あなたは忘れるしたいという例外的なケースのためのアサーションを使用して、忘れなければならないということです対処する必要があります。 "
残念ながらに無効にすることができます主張しています。生産にあなたが何か不測のを追跡得ることができるすべての助けを必要とするとき、そう自分を失格主張します。