Using AssertionError and assertions in java
assertions, exception, java
Solution
In the technote "Programming With Assertions: Control Flow Invariants" the following code is given:
void foo() {
for (...) {
if (...)
return;
}
assert false; // Execution should never reach this point!
}
But the following note is given as well:
Note: Use this technique with discretion. If a statement is unreachable as defined in the Java Language Specification, you will get a compile time error if you try to assert that it is not reached. Again, an acceptable alternative is simply to throw an AssertionError.
You may not expect an `AssertionError` to be thrown when assertions are turned off. As `AssertionError` constructors are public, and since there is likely no substitution for `AssertionError(String message, Throwable cause)`, I guess that you should expect them even if they are turned off.
Throwing an `AssertionError` on unreachable code (i.e. without any real expression to be evaluated) will never slow down the code, as Jon Skeet suggested, so it won't hurt with regards to performance.
So in the end throwing the `AssertionError` seems OK.
Problem
I use assertions in Java in a standard way, having them turned on in my IDE. So they are not part of production release. Lately I have been seeing code examples with `throw new AssertionError()` and I started thinking about the situation where `AssertionError` should be used instead of assertion. My guess is that main difference is the optionality of asserts so they don't slow down the production performance and so they can occur quite often in the code, but fixing hardly reproducible bugs reported from users is harder. For `AssertionError`, the exact opposite applies. I also find `AssertionError` more practical in places in code where the execution should not get, instead of using `assert false //We should not be here`. Especially if the return value is required. For example: ``` int getFoo(AnEnum a){ if (a == AnEnum.ONE) return bar(); else if (a == AnEnum.TWO) return SOME_VALUE; //else assert false; //throw new AssertionError(); return -1; //not necessary when usin AssertionError } ``` - Is my reasoning correct? - What are the other differences/use cases/best practices/limitations of either approach? - In regards to providing a description in the `AssertionError` - Should it be provided or is the mere fact that it is an `Error` (and of assertion type) enough to be more or less sure that stack trace will be provided in case of found bugs?