web-dev-qa-db-ja.com

AssertionErrorとは何ですか?どの場合、自分のコードからそれをスローする必要がありますか?

「Effective Java、2nd edition」ブックのItem 2には、このコードスニペットがあり、著者はオブジェクトの空の初期化を禁止したいと考えています。

class Example {
    private Example() {
        throw new AssertionError();
    }
}

スローされる例外のタイプは、ここで私を混乱させるものです。

AssertionErrorがスローされるのは、より適切なエラーがないためにスローされるのか、それともこのようにする必要があるのか​​がわかりません。

私が理解しているように、このエラーはassertステートメントが失敗したときにフレームワークによってスローされます。また、javadocには次のように書かれています。

[AssertionError is]アサーションが失敗したことを示すためにスローされます。

ただし、ここで違反されているアサーション(true-falseステートメント)は表示されません。もちろん、「このクラスのアイテムをインスタンス化してはならない」ステートメントに違反していますが、これがその背後にあるロジックである場合は、すべての場所にAssertionErrorsをスローする必要があります。

FWIW、私はちょうど投げていただろう

new IllegalStateException("Must not instantiate an element of this class")

それに何か問題がありますか?どの場合、自分のコードでAssertionErrorをスローする必要がありますか?

ちょっとした疑いがある場合は申し訳ありませんが、このパターンをコードで頻繁に使用しており、正しいことを確実に実行したいと考えています。

57
doplumi

もちろん、「このクラスの項目をインスタンス化してはならない」ステートメントに違反していますが、これがその背後にあるロジックである場合、すべての場所でAssertionErrorsをスローする必要があります。

コードは、ユーザーが引数ゼロのコンストラクターを呼び出さないと言っているわけではありません。アサーションは、プログラマーが知っている限り、ゼロ引数コンストラクターを呼び出す不可能にした(この場合はprivateにしてExampleのコード内から呼び出さないでください)。したがって、呼び出しが発生した場合、そのアサーションに違反しているため、AssertionErrorが適切です。

37
T.J. Crowder

AssertionErrorの意味は、開発者が発生するのは不可能だと思った何かが発生したということです。

したがって、AssertionErrorがスローされる場合は、プログラミングエラーの明確な兆候です。

28
Henry

アサーションエラーがスローされるのは、「あなたのロジックによれば、実行すべきではないので、決して実行すべきでないコードを記述しました。しかし、発生した場合、AssertionErrorをスローします。このような場合、アサーションエラーをスローします。

new IllegalStateException("Must not instantiate an element of this class")' // Is an Exception not error.

注:アサーションエラーは、Java.lang.Errorおよびエラーをキャッチすることを意図していません。

14
Oliver

私は本当にここでパーティーに遅れていますが、答えのほとんどは、特にAssertionErrorを使用するのではなく、一般的にアサーションを使用する理由と時期に関するもののようです。

assertthrow new AssertionError()は非常に似ており、同じ概念上の目的を果たしますが、違いがあります。

  1. throw new AssertionError()は、アサーションがjvmに対して有効になっているかどうかに関係なく(つまり、-eaスイッチを介して)例外をスローします。
  2. コンパイラーは、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がコードの出力を試みるまでに初期化されたことを保証できないためです。

1
Matthew McPeak

AssertionErrorは、プログラマーまたはAPI開発者によって明示的に発生してアサートステートメントが失敗したことを示す、チェックされない例外です。

assert(x>10);

出力:

AssertionError

Xが10より大きくない場合、AssertionErrorというランタイム例外が発生します。

0
Raman Gupta