「Effective Java、2nd edition」ブックのItem 2には、このコードスニペットがあり、著者はオブジェクトの空の初期化を禁止したいと考えています。
class Example {
private Example() {
throw new AssertionError();
}
}
スローされる例外のタイプは、ここで私を混乱させるものです。
AssertionError
がスローされるのは、より適切なエラーがないためにスローされるのか、それともこのようにする必要があるのかがわかりません。
私が理解しているように、このエラーはassert
ステートメントが失敗したときにフレームワークによってスローされます。また、javadocには次のように書かれています。
[AssertionError is]アサーションが失敗したことを示すためにスローされます。
ただし、ここで違反されているアサーション(true-falseステートメント)は表示されません。もちろん、「このクラスのアイテムをインスタンス化してはならない」ステートメントに違反していますが、これがその背後にあるロジックである場合は、すべての場所にAssertionError
sをスローする必要があります。
FWIW、私はちょうど投げていただろう
new IllegalStateException("Must not instantiate an element of this class")
それに何か問題がありますか?どの場合、自分のコードでAssertionError
をスローする必要がありますか?
ちょっとした疑いがある場合は申し訳ありませんが、このパターンをコードで頻繁に使用しており、正しいことを確実に実行したいと考えています。
もちろん、「このクラスの項目をインスタンス化してはならない」ステートメントに違反していますが、これがその背後にあるロジックである場合、すべての場所で
AssertionErrors
をスローする必要があります。
コードは、ユーザーが引数ゼロのコンストラクターを呼び出さないと言っているわけではありません。アサーションは、プログラマーが知っている限り、ゼロ引数コンストラクターを呼び出す不可能にした(この場合はprivate
にしてExample
のコード内から呼び出さないでください)。したがって、呼び出しが発生した場合、そのアサーションに違反しているため、AssertionError
が適切です。
AssertionError
の意味は、開発者が発生するのは不可能だと思った何かが発生したということです。
したがって、AssertionError
がスローされる場合は、プログラミングエラーの明確な兆候です。
アサーションエラーがスローされるのは、「あなたのロジックによれば、実行すべきではないので、決して実行すべきでないコードを記述しました。しかし、発生した場合、AssertionErrorをスローします。このような場合、アサーションエラーをスローします。
new IllegalStateException("Must not instantiate an element of this class")' // Is an Exception not error.
注:アサーションエラーは、Java.lang.Errorおよびエラーをキャッチすることを意図していません。
私は本当にここでパーティーに遅れていますが、答えのほとんどは、特にAssertionError
を使用するのではなく、一般的にアサーションを使用する理由と時期に関するもののようです。
assert
とthrow new AssertionError()
は非常に似ており、同じ概念上の目的を果たしますが、違いがあります。
throw new AssertionError()
は、アサーションがjvmに対して有効になっているかどうかに関係なく(つまり、-ea
スイッチを介して)例外をスローします。throw new AssertionError()
がブロックを終了することを知っているため、これを使用すると、assert
では発生しない特定のコンパイラーエラーを回避できます。例えば:
{
boolean b = true;
final int n;
if ( b ) {
n = 5;
} else {
throw new AssertionError();
}
System.out.println("n = " + n);
}
{
boolean b = true;
final int n;
if ( b ) {
n = 5;
} else {
assert false;
}
System.out.println("n = " + n);
}
上記の最初のブロックは、問題なくコンパイルされます。 2番目のブロックはコンパイルされません。これは、コンパイラがn
がコードの出力を試みるまでに初期化されたことを保証できないためです。
AssertionErrorは、プログラマーまたはAPI開発者によって明示的に発生してアサートステートメントが失敗したことを示す、チェックされない例外です。
assert(x>10);
出力:
AssertionError
Xが10より大きくない場合、AssertionErrorというランタイム例外が発生します。