Daniel Dyer said:
Getting back to the original poster's question about the use of
IllegalArgumentException, I would say that it should be used to validate
that arguments are acceptable according to the specification of the method
(which should be documented). Therefore you should know for certain
before you call the method (or constructor) with a given set of arguments
whether an exception will result. If you know this for certain in advance
you can avoid it. If you can write the code in such a way that this
exception is guaranteed never to occur it makes no sense to make the
exception checked or even to catch it.
Agreed. In some cases, the focus on avoidability is very enlightening.
I'd be more precise and say the question is who "should" realize that
the argument is wrong. In many cases, libraries are computationally
deterministic and it's possible to avoid passing bad arguments, but the
question is still decided by where the detection of bad arguments ought
to occur. If the calling code "should" have known about the problem
before calling the method, then it is a programmer error. If the code
being called is the first location that "should" recognize a problem
with the arguments.
For example, it may be a requirement that some argument needs to be
relatively prime to some intermediate result from a complex math
calculation. If the complex math calculation is pertinent to the
library's problem space, then the logic for checking the input most
likely logically belongs to the library. IllegalArgumentException is
not appropriate in that case. The same is true for most parsing code.
Invariably, when explaining this, someone asks about the standard API,
NumberFormatException, and Integer.parseInt. This is a border case, but
the reasoning is basically this: NumberFormatException should only be
used for data that's produced programmatically, stored as text, and then
read back. If nothing goes wrong, there is no possibility of getting a
badly formatted number. User input (which often uses parseInt in
practice, IME) ought to be using the java.text.NumberFormat class --
which, lo and behold, throws a checked exception onm failure. The
border-ness comes from the fact that some "advanced" users are
inevitably going to view and try to edit an application's internal data
files when they are stored as text. These users, when they screw
something up, might arguably deserve better than an application crash
for it.
As Chris pointed out, there is no good reason to write another exception
type for this purpose.
Hmm. I actually said there's no good reason to throw a checked
exception. Although you're obviously not thinking of this, there could
be a very good reason to throw a subclass of IllegalArgumentException,
which means writing a new exception type. Off-hand, this could be done
because it might be useful to include more information or context about
why the argument was illegal.
In any case, some time ago I wrote a short presentation for the Pikes
Peak Java Developers Group on exception handling practices. You can
find it at:
--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.
Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation