2009-08-14 13 views
46

Java例外処理とassert条件の違いは何ですか?例外とVアサーション

アサートは2種類あります。しかし、いつ我々はassertキーワードを使用する必要がありますか?

+0

私は自分の目を信じることができません:この質問は実際に166kのユーザーによって編集されましたが、それはまだこのように見えます! –

+1

ええ、かなり悪いです。私はもう少しそれをきれいにした。 JavaRespが "2つのタイプ"で意味することは分かりませんので、そこに残しておきます。私の推測は、http://www.deitel.com/articles/java_tutorials/20060106/Assertions.html –

+0

によると、前提条件と事後条件との間にあります。この場合、「いくらか」は「全体的な改訂」を意味します。 – JakeSteam

答えて

72

コード内の内部ロジックチェックにアサーションを使用し、イミディエートコードのコントロール外のエラー条件に対しては通常の例外を使用します。

アサーションをオンまたはオフにすることができることを忘れないでください。引数の検証などのことを気にする場合は、例外を使用して明示的に指定する必要があります。 (ただし、アサーションを使用してprivateメソッドで引数の検証を実行することもできますが、そのときの違反は外部エラーではなく内部バグが原因です)。

また、 IMO)を使用してすべての例外を使用します。私は個人的にアサーションをまったく使用しませんが、それはある程度個人的な好みの問題です。アサーションに対する客観的な議論は確かにあるかもしれませんが、全体的に優先度を取り除くのには十分に明確ではありません。)

+4

一部の言語では、実際に例外を使用してアサーションを実装しています。そのような言語では、「あらゆるものに例外を使用することは合理的です」という文章は冗長なものです。 :) – Imagist

+0

[dasblinkenlight](http://programmers.stackexchange.com/a/137167/175034)で指定されているように:「チェックされていない例外は、ライブラリのユーザーのプログラミングエラーを検出するように設計されていますが、アサーションはエラーを検出するように設計されていますあなた自身のロジックでは、これらは混在すべきではない別々の問題です」。 – MaxZoom

1

アサートはデバッグ目的のみであり、トリガー条件は起こらないはずですするFileNotFound、ConnectionToServerLostなど

6

例外は、実装が任意の予想または予期しないエラーやないなしで実行されているかどうかをチェックする仕組みである:、など)

例外が常に発生する可能性があり、特別なシステムイベントのためです。したがって、例外は基本的に、アプリケーションの実行中に予期せぬ条件を処理するために使用されるため、例外を使用すると効果的に堅牢なアプリケーションになります。

アサーションは、アプリケーションの一部の機能の実装の一部であってはなりません。これらは、仮定を検証するためにのみ使用してください。実際に解決策を検討している間に想定したものは実際には有効であることを確認してください。

参照:http://geekexplains.blogspot.com/2008/06/asserions-in-java-assertions-vs.html

24

Javaのアサーションは、Javaの例外と例外処理の上に構築されています。実際、Javaのアサーションが失敗した場合、他のJavaの例外と同様にキャッチすることができるAssertionError例外が発生します。例外とアサーションの主な違いは以下のとおりです。

  • アサーションは単にバグ別名、プログラミングエラーを検出する手段として使用されることをを目的としています。対照的に、例外は他の種類のエラーまたは「例外的な」状態を示すことができます。例えば無効なユーザー入力、ファイルの欠落、ヒープいっぱいなどです。
  • Java言語は、アサーションの構文サポートをassertステートメントの形式で提供します。次の比較:

    if (x != y) { 
        throw new SomeException("x != y"); 
    } 
    
    assert x != y; 
    
  • 最も重要なのは、JavaはあなたがJVMを起動するときに、グローバルまたは個々のクラスにチェックアサーションを有効または無効にすることができます。

注:一部の人々はあなたがアサーションと常に実行プロダクションコードをオフにチェックすべきであると言います。私は毛布の声明としてこれに同意しない傾向があります。プロダクションコードが安定していることがわかっていて、その最後のパフォーマンスビットを絞る必要がある場合は、アサーションをオフにするのが良いです。しかし、10%のパフォーマンスヒットが本当の問題ではない場合、私は、代替が続行され、データベースが壊れていると、アサーションエラーでアプリケーションが死ぬことを望んでいます。

@MarioOrtegónは、このようにコメント:

アサーションはよく知られているが、遅い、アルゴリズムに対して、その実装を比較することによって、最適化アルゴリズムの結果を検証するために使用することができるので、「オフ」です。したがって、開発中にO(log N)アルゴリズムが意図したとおりに動作することをアサートするために、そのO(N^3)メソッドを呼び出すことはOKです。しかし、これはあなたが生産では望まないものです。

あなたは生産にアサーションをオフにする良い練習だと思うかどうかにかかわらず、間違いなく有効なパフォーマンスに大きな影響を持っているアサーションを記述する悪い習慣です。どうして?これは、プロダクションでアサーションを有効にするオプション(問題をトレースする)やストレス/容量テストでオプションを使用できなくなったためです。私の意見では、O(N^3)プレ/ポストコンディションテストを行う必要がある場合、あなたはユニットテストでそれを行うべきです。アサートの良い使用の

+0

「ターンオフ」は、アサーションを使用して、その実装をよく知られているが遅いアルゴリズムと比較することによって、最適化されたアルゴリズムの結果を検証することができるためです。だから、開発では、O(n3)メソッドを呼び出して、O(log N)アルゴリズムがintentedとして動作することを宣言してもいいです...しかし、あなたが*生産では望まないものがあります。 –

4

例:

assert flibbles.count() < 1000000; // too many flibbles indicate something is awry 
log.warning("flibble count reached " + flibbles.count()); // log in production as early warning 

私は個人的にあなたが何かが外望ましいの限界を知っているときアサートがのみ使用することべきであると思いますが、あなたはそれが合理的に安全で確認することができます持続する。他のすべての状況(私が考えていない自由な指摘の状況を感じてください)では、例外を使って難しく速く失敗します。

あなたが破損を避けるために、例外でライブ/生産システムをダウンさせると簡単にトラブルシューティングをしたいかどうか、私にとって重要なトレードオフがある、またはあなたがテストで見過ごされ続けることを許可すべきではない状況に遭遇したかどうか/バージョンをデバッグすることはできますが、プロダクションでは継続することができます(もちろん警告を記録する)。

cf. http://c2.com/cgi/wiki?FailFastこの回答のも​​、私のC#のコピーを参照してください。Debug.Assert vs. Specific Thrown Exceptions

+3

アサーションは、それよりはるかに強力です。これらは、コード内の特定のポイントで*常に*真であることについての前提や保証を文書化する(そして、デバッグ時に実行するときに検証する)ことを意図しています。 **アサーションの失敗は決して起こるべきではありません** - もしそうであれば、それはあなたの前提が間違っていたことを意味します、そして、(b)その後のコードは正しいことをすることができません行に沿って、それは*既に行われている*間違ったこと、そして今それは "範囲外"で動作している)。 – cHao

+0

何か起こるべきではないことが分かっている場合、なぜアサーションがオフになっているプロダクションコードでチェックが外れてしまいますか?確かに、壊れた前提が捕らえられていることを確認するために例外を使用します。私はここに受け入れられた知恵に逆らっていることを知っていますが、私は逆説的であることで何が魅力的な議論をするのか興味を持っています。ご意見ありがとうございます! –

+1

例外は通常は起こらないものの、可能性があります。ファイルの欠落、ネットワークの停止、おそらく無効なデータ。あなたのコードは制御できません。アサーションは、あなたのコードが適切に動作していれば、*決して*起こるものではありません。それらはデバッグ中にダブルチェックとして意味されます。プロダクションでは、コードではすでにチェックしなくても十分な結果が得られるはずです。 – cHao

0

アサーションは、唯一の例外は、実行中にチェックする特定の条件をチェックすることですしながら、アサート機能を有効にすることによって、実行時にチェックするために必要な仮定のデバッグに使用されますプログラムが終了するのを防ぐためのプログラム。

4

アサーションは例外と非常によく似ていますが、実際には例外のようにフラグを付けますが、例外とは異なり、代わりの実行パスは示唆されませんが、単に失敗します。 アサーションを使用する理由、同じことをすることができますか?

問題が解決されるべきではない場合に使用してください。実際には、最初の場所には絶対に置かないでください。これは最初は奇妙に聞こえます。すべての潜在的な問題からコードを守りたいのではないでしょうか?通常はい。しかし、私たちがしないケースがあります。このケースは「契約による設計」と呼ばれます。

たとえば、銀行向けのアプリケーションを作成しているとします。開発者は、可能なすべての財務状況をサポートすることはできません。したがって、コードを作成する前に、このアプリケーションがサポートする必要がある有効な範囲を与える仕様を銀行から取得します。したがって、アプリケーションは契約書に基づいて設計されています(銀行の仕様による)。この契約は、アプリケーションが機能するためには常に真実でなければならない基本原則を定義します。これらの基本原則は、(不変であるため)不変条件と呼ばれています。契約書によるデザインは、開発者としてのあなたの人生を簡素化します。契約で定義されている作業範囲をサポートする責任があります。
これらのインバリアントの値をコード内でチェックすることは重要ですが、例外であるかのようにチェックして回避することはできません。彼らが間違っている場合、入力が契約上の義務を果たさなかったために失敗しなければなりません。

興味深いのは、重要な場所にアサーションを入れず、インバリアントが無効になっても、コードは失敗するということです。理由を知らないだけです。要約すると、アサーションは、不変量を検証するために使用されます。彼らは "契約による設計"の原則と協力して行動します。それらを使用して問題をデバッグします。つまり、プロダクションでそれらがオフになっている理由です。

もう1つの使用例:完全に信頼していない外部ライブラリに頼っている場合は、呼び出し時にアサートステートメントを使用することができます。

また、アサーションは、例外のための迅速で汚れた代用として(それほど簡単なので)、概念的にはそれが適切ではありません。