Java の経験が限られているため、アサーションを実際に扱ったことがなく、アサーションを扱う多くのサイトや多くの本を読んだのはなぜだろうと思っていました。 assert ステートメントは引数のチェックに使用すべきではないという同じ警告です。パブリックメソッドで?
これは、Java の他のステートメントに対する assert ステートメントの実行順序と関係があるのではないかと考えていました。
非公式には、引数のチェックとアサーションは異なる目的を果たします。
基本的に、条件をアサートするとき
assert val < total;
チェックは、コードの読者に次の平易な英語の考えを伝えval
ますtotal
。
val
一方、引数をチェックすると、
if (val >= total) throw new InvalidArgumentException("val");
あなたのコードは、「呼び出し元がval
がより小さいことを確認するのを忘れた」と言っていますtotal
。
これらは 2 つの異なる考えであるため、コードでそれらを伝えるために 2 つの異なる方法を採用するのは自然なことです。
アサーションの目的は、プログラム ロジックをチェックすることです。アサーションの失敗は、「すべてを停止してください。バグがあります!」ということです。表示。特に、アサーションの失敗は「ここにバグがある」ことを示しますが、「ここ」はコードの内部のどこかにあり、失敗の原因は実際にはコードを調べることによってのみ特定できます (API のユーザーはできませんし、そうすべきです)。することは期待されていません)。
API で不正なデータを取得した場合は、「おやおや、不正なデータが表示されました!」と示す必要があります。IllegalArgumentException とその類は、それを示す方法です。
(ただし、コード内のパラメーターでアサーション チェックを使用しても問題はありません。チーム外の人々が使用する真の「パブリック」API をサポートしていない場合です。)
しかし、これは別のポイントをもたらします: 合理的/可能な範囲で、自分のバグが原因で発生する可能性のある IllegalArgumentException 同類の内部例外を「キャッチ」し、それらを FatalError 例外などに変換する必要があります。コードにバグがある場合、彼の側で悪いパラメーターを探しに行くように導かれることはありません。
(また、Java キーワードと「パブリック インターフェイス」の違いにも注意してpublic
ください。これは、プログラミング チーム以外の個人が使用する「正式な」API として利用できるインターフェイスを意味します。後者の場合です。ここが気になります。)
引数のチェックは通常、公開されているメソッドの仕様 (またはコントラクト) の一部であり、アサーションが有効か無効かに関係なく、これらの仕様に従う必要があります。引数チェックにアサーションを使用する場合のもう 1 つの問題は、誤った引数によって適切な実行時例外 (IllegalArgumentException、IndexOutOfBoundsException、または NullPointerException など) が発生することです。アサーションの失敗は、適切な例外をスローしません。
1 つには、Java アサーションは、コンパイル時に明示的に有効にしない限り、実行時に削除されます。
例外は、それらを処理することを期待しているため、パラメーターの検証に適していますが、アサーションには「コードのこの時点でこれが真でなければならない、またはこれを処理する方法がわかりません」という意味があります。
本番ビルドではアサーションが無効になっているためです。パブリック メソッドが誤って使用されたときにキャッチできるようにする必要がある場合、アサーションは製品ビルドでチェックをトリガーせず、例外はエラーを通知するためのより良い方法になります。
これはライブラリにとって特に重要です。なぜなら、誰がどのようにメソッドを呼び出すかを制御できないからです。アプリケーション プログラムの場合、パブリック メソッドでのアサーションは、適切な入力検証 (「入力」がユーザー入力、別のシステムからの入力、または永続ストレージからの入力のいずれか) がある場合に限り問題ありません。トリガーされます。