Re: Where shoul I throw RuntimeException
Giovanni Azua wrote:
Hi Eric,
"Eric Sosman" <Eric.Sosman@sun.com> wrote
because ... ?
Because they [assertions] can be turned off at run-time, leaving you with
no validity-checking at all.
In general I disagree with this rule "do not use assertions to check the
parameters of a public method":
http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html#usage-conditions
These would be the possible scenarios interacting with an API:
1-. Human to software interaction: end-user enters data
2-. External system to software interaction: binary interoperability of
separate components e.g. MOM
3-. Software to software interaction: a library e.g. JDK is being used to
develop some application
In cases #1 and #2 it is necessary to use exceptions e.g.
IllegalArgumentException to deal with *Input Validation*. This is because #1
and #2 are the front-line layers that deal with input outside the control of
the application. These are the "filter modules" to the outside world. Using
assertions to deal with Input Validation indeed would be wrong and "wishful
thinking" as Bertrand Meyer calls it.
Now point #3 is the case of application interacting with a library e.g. JDK.
There is no external wrong input to deal with but only programming errors, a
precondition violation is a programming error in the client of the routine
or class. Programming errors must be discovered during testing and debugging
cycles when assertions are enabled and not in production.
I just want to stress that there is a difference between Input Validation
and preconditions checks (assertions):
"Object Oriented Software Construction 2nd Edition" Bertrand Meyer, page 345
"Assertions are not an input checking mechanism".
I also included a note on this, see "Defensive Programming Approach":
http://perfectjpattern.sourceforge.net/design-notes.html
In the context of a public method, I think any difference
between validation and precondition checking pretty much vanishes.
The writer of a public method (or protected) method has no control
over the method's callers, and can't even enumerate them (the
trouble with code re-use is that people re-use code). The argument
values provided by those callers are just as untrustworthy as data
read from any uncontrolled source, and should be given the same
kinds of screening. And, I believe, should provoke the same kind
of response if the screening detects anomalies.
Thought experiment: Should the array-accessing operation treat
the index value as an input to be validated, or as a precondition
whose validity has been established during the testing phase and
need not be checked thereafter? That is, would you be in favor of
checking indices with an assert-like mechanism that could be turned
off once the code had passed enough tests? Surely it's a programming
error if the code generates an invalid index; should the detection
of that error be suppressable?
Your distinction between validation and precondition checking
is, I think, a reasonable one to draw in private and package-
private methods. But a public or protected method is too "exposed"
to take advantage of such a distinction, and should IMHO treat all
inputs as coming from "the outside."
--
Eric.Sosman@sun.com