90

In Item 2 of the "Effective Java, 2nd edition" book, there is this snippet of code, in which the author wants to forbid the empty initialization of an object.

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

The type of exception thrown, is what confuses me here.

I don't understand if the AssertionError is thrown just because of an absence of more suited errors or because it should be this way.

As I understand, this error is thrown by the framework when an assert statement fails. Also, in the javadoc it's just written

[An AssertionError is] Thrown to indicate that an assertion has failed.

But I don't see any assertion (true-false statement) being violated here. Of course the "You shall not instantiate an item of this class" statement has been violated, but if this is the logic behind that, then we should all throw AssertionErrors everywhere, and that is obviously not what happens.

FWIW, I'd have just thrown a

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

Is there something wrong with that? In which case should I throw an AssertionError in my own code?

Sorry if it's just a subtle doubt but I use this pattern a lot in my code and I want to make sure I'm doing the right thing.

doplumi
  • 2,938
  • 4
  • 29
  • 45
  • 3
    "Assertions" doesn't just mean "`assert` statements". – user253751 Jul 21 '14 at 10:45
  • 2
    Guava has a [useful reference](https://github.com/google/guava/wiki/ConditionalFailuresExplained) comparing several different use-cases for runtime exceptions and `AssertionError`. I'd encourage anyone who is surprised by this pattern to read this page. – dimo414 Dec 25 '16 at 22:37

5 Answers5

65

Of course the "You shall not instantiate an item of this class" statement has been violated, but if this is the logic behind that, then we should all throw AssertionErrors everywhere, and that is obviously not what happens.

The code isn't saying the user shouldn't call the zero-args constructor. The assertion is there to say that as far as the programmer is aware, he/she has made it impossible to call the zero-args constructor (in this case by making it private and not calling it from within Example's code). And so if a call occurs, that assertion has been violated, and so AssertionError is appropriate.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 4
    That makes sense. So throwing that exception would be like creating an assertion and giving the value `false` to it all at once, do you agree with that? – doplumi Jul 21 '14 at 11:03
  • @domenicop: You've got it.!! – Oliver Jul 21 '14 at 11:04
  • Note that you could also use `assert false`. More on that [here](http://stackoverflow.com/q/22053306/589259) – Maarten Bodewes Aug 01 '14 at 19:26
  • 15
    @MaartenBodewes: Be careful, using `assert false` is different from `throw new AssertionError();`. The former will only throw an error if the java programm is started with assertions enabled, whereas the latter will always throw the assertion. – Mathias Bader Dec 25 '16 at 21:41
49

The meaning of an AssertionError is that something happened that the developer thought was impossible to happen.

So if an AssertionError is ever thrown, it is a clear sign of a programming error.

Henry
  • 42,982
  • 7
  • 68
  • 84
23

An assertion Error is thrown when say "You have written a code that should not execute at all costs because according to you logic it should not happen. BUT if it happens then throw AssertionError. And you don't catch it." In such a case you throw an Assertion error.

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

Note: Assertion Error comes under java.lang.Error And Errors not meant to be caught.

Oliver
  • 6,152
  • 2
  • 42
  • 75
  • thank you, I was actually confusing a RuntimeException with an Error here, though I wonder if the difference it's just in "they're not meant to be caught", or "the compiler will refuse to compile your code if you catch them" – doplumi Jul 21 '14 at 10:58
  • 2
    No you can do stuff like `catch(Throwable t){}` But this is very bad code. Error and Throwable should not be caught. Lets say you get a `OutOfMemoryError` and you catch that imagine you are out of RAM and your still runing ur app. This will won't be good. You'll blow your PC off(Just kidding). – Oliver Jul 21 '14 at 11:02
11

I'm really late to party here, but most of the answers seem to be about the whys and whens of using assertions in general, rather than using AssertionError in particular.

assert and throw new AssertionError() are very similar and serve the same conceptual purpose, but there are differences.

  1. throw new AssertionError() will throw the exception regardless of whether assertions are enabled for the jvm (i.e., through the -ea switch).
  2. The compiler knows that throw new AssertionError() will exit the block, so using it will let you avoid certain compiler errors that assert will not.

For example:

    {
        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);
    }

The first block, above, compiles just fine. The second block does not compile, because the compiler cannot guarantee that n has been initialized by the time the code tries to print it out.

Matthew McPeak
  • 17,705
  • 2
  • 27
  • 59
-4

AssertionError is an Unchecked Exception which rises explicitly by programmer or by API Developer to indicate that assert statement fails.

assert(x>10);

Output:

AssertionError

If x is not greater than 10 then you will get runtime exception saying AssertionError.

Raman Gupta
  • 1,580
  • 15
  • 12
  • 6
    Wrong. Errors are not Exceptions. Specifically, AssertionError is not a subclass of RuntimeException, so it is not an unchecked exception. – i2B Sep 26 '19 at 18:48