assert
Javaの例外処理と条件の使用の違いは何ですか?
Assert には 2 つのタイプがあることが知られています。しかし、いつassert
キーワードを使用する必要がありますか?
コード内の内部ロジック チェックにはアサーションを使用し、直接のコードの制御外のエラー条件には通常の例外を使用します。
アサーションはオンとオフを切り替えることができることを忘れないでください。引数の検証などに関心がある場合は、例外を使用して明示的に行う必要があります。(ただし、その時点での違反は外部エラーではなく内部バグによるものであるという理由で、アサーションを使用してプライベートメソッドで引数の検証を実行することを選択できます。)
あるいは、すべてに例外を使用することは完全に合理的です (IMO)。私は個人的にアサーションをあまり使用しませんが、ある程度は個人的な好みの問題です。(確かに、主張に賛否両論の客観的な議論が存在する可能性はありますが、選好を完全に取り除くには十分に明確ではありません。)
Java アサーションは、Java 例外と例外処理の上に構築されます。実際、Java アサーションが失敗すると、結果は AssertionError 例外となり、他の Java 例外と同様にキャッチできます。例外とアサーションの主な違いは次のとおりです。
assert
Java 言語は、ステートメントの形式でアサーションの構文サポートを提供します。以下を比較してください。
if (x != y) {
throw new SomeException("x != y");
}
assert x != y;
最も重要なことは、Java を使用すると、JVM の起動時にグローバルまたは個々のクラスでアサーション チェックを有効または無効にできることです。
注:アサーション チェックをオフにして、常に製品コードを実行する必要があると言う人もいます。私はこれを包括的声明として反対する傾向があります。本番コードが安定していることがわかっていて、パフォーマンスの最後のビットを絞り出す必要がある場合は、アサーションをオフにすることをお勧めします。しかし、(たとえば) 10% のパフォーマンス ヒットが実際の問題ではない場合、別の方法が続行されてデータベースが破損する場合は、アサーション エラーでアプリケーションを終了させたいと思います。
@Mario Ortegón は次のようにコメントしています。
「オフにする」のは、アサーションを使用して、最適化されたアルゴリズムの結果を、その実装をよく知られているが遅いアルゴリズムと比較することによって検証できるためです。したがって、開発では、そのメソッドを呼び出して、アルゴリズムが意図したとおりに機能
O(N^3)
することをアサートしても問題ありません。O(log N)
しかし、これは本番環境では望ましくありません。
本番環境でアサーションをオフにすることが良い習慣だと思うかどうかにかかわらず、有効にしたときにパフォーマンスに大きな影響を与えるアサーションを書くことは間違いなく悪い習慣です。なんで?これは、本番環境 (問題を追跡するため) またはストレス/容量テストでアサーションを有効にするオプションがなくなったことを意味するためです。私の意見では、O(N^3)
事前/事後条件テストを行う必要がある場合は、単体テストで行う必要があります。
例外は、実装が予想または予期しないエラーなしで実行されているかどうかをチェックするメカニズムです。したがって、例外は基本的に、アプリケーションの実行中に予期しない状況をより適切に処理するために使用されるため、例外を効果的に使用すると堅牢なアプリケーションが得られることがわかります。
アサーションは、アプリケーションの一部の機能の実装の一部であってはなりません。それらは、仮定を検証するためにのみ使用する必要があります。ソリューションを設計する際に想定したことが実際に有効であることを確認するためです。
参照: http://geekexplains.blogspot.com/2008/06/asserions-in-Java-assertions-vs.html
Assert の適切な使用例:
assert flibbles.count() < 1000000; // too many flibbles indicate something is awry
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning
個人的には、何かが望ましい制限を超えていることがわかっている場合にのみAssert を使用する必要があると思いますが、続行しても合理的に安全であると確信できます。他のすべての状況 (私が思いもよらなかった状況を自由に指摘してください) では、例外を使用して、ハードかつ迅速に失敗します。
私にとっての重要なトレードオフは、破損を回避してトラブルシューティングを容易にするために、ライブ/本番システムを例外でダウンさせたいかどうか、またはテスト/デバッグ バージョンで見過ごされてはならない状況に遭遇したことがあるかどうかです。本番環境での継続が許可されます (もちろん警告をログに記録します)。
参照。http://c2.com/cgi/wiki?FailFastこの回答の私の c# コピーも参照してください: Debug.Assert vs. Specific Thrown Exceptions
アサーションと例外処理の両方により、プログラムの正確性を保証し、論理エラーを回避できます。
ただし、アサーションはプログラマーの希望に応じて有効化および無効化できます。
コンパイラで「java -ea JavaFileName」または「java -enableasserations JavaFileName」を使用すると、アサーションでコンパイルできます
プログラマーがそれを必要としない場合は、「java -da JavaFileName」または「java -disableasserations JavaFileName」でアサーションを無効にできます。
この機能は例外処理にありません
アサートはデバッグのみを目的としており、そのトリガー条件は発生してはなりません (発生してはならない場合の null ポインターなど)。
例外は、常に発生する可能性がある特別なシステム イベント (FileNotFound、ConnectionToServerLost など) です。
アサーションは、アサート機能を有効にすることによってのみ実行時にチェックされる必要な前提条件のデバッグに使用されますが、例外は、プログラムの実行中にチェックされる特定の条件をチェックして、プログラムが終了しないようにすることです。