Twisted said:
With asserts now in Java, which places where one formerly threw
RuntimeExceptions (and Errors) might be better off changed to asserts?
(Can't happens, of course, but where else? Everywhere you threw
nullpointerexception? What about arithmetic exceptions? Obviously not
anywhere the exception's expected to be caught and handled somehow,
such as just skipping over a value that causes an arithmetic exception
when graphing a function...)
What's currently considered "best practise" in this area?
As a general rule of thumb, use an assertion when the following three
propositions are true:
1. You know that something is wrong.
AND
(2a. Failure won't be immediate and obvious.
OR
2b. You can provide a very helpful detail message.)
AND
3. This is NOT part of the interface to published or reusable code.
In these cases, an assertion may be a little more readable than throwing
a runtime exception. Whether you replace existing exceptions with
assertions depends on how you've used exceptions in the past; but the
default answer ought to be "no." You may consider replacing some
explicit "throw" statements with assertions. However, you certainly
don't want to hunt down sources of implicit (not explicitly thrown)
runtime exceptions and replace them with assertions; after all, if you
know that an exception will be thrown, then #2a is false, and an
assertion is not needed unless you can be helpful enough in your message
to justify cluttering the code. For example:
assert b != null : "Gizmo needs to armed before widget is tweaked.";
b.tweak();
might be justified, but:
assert b != null : "Widget is null";
b.tweak();
is probably bad code. Anyone who's ever seen the word Java is capable
of reading the next line and realizing why they got a
NullPointerException. They don't need to you inform them that the
variable was null. That's just useless clutter that obscures the
function of your code.
Regarding #3: Remember that assertions may be disabled, so you can't
rely on them to check things like preconditions of relatively widespread
APIs. It may be tempting, but the long-term result will be that users
will stop trusting your APIs because they won't enable those assertions.
So never replace IllegalArgumentException or IllegalStateException with
an assertion. Often, explicit throws of RuntimeException fall into this
category, so be careful about replacing them.
The assert keyword is sometimes even outright forbidden by definite
assignment rules. For example, this doesn't work:
String name;
if (hasName()) name = getName();
else assert false : "No name";
So how often do assertions meet this test? Depends on your standard for
how much clutter is tolerable and how reusable something needs to be
before you enforce its preconditions religiously. As one data point, I
have never used an assertion in production code in Java.