The
basic philosophy of Java is that “badly-formed code will not be run.”
As
with C++, the ideal time to catch the error
is at compile time, before you even try to run the program. However, not all
errors can be detected at compile time. The rest of the problems must be
handled at run-time through some formality that allows the originator of the
error to pass appropriate information to a recipient who will know how to
handle the difficulty properly.
In
C and other earlier languages, there could be several of these formalities, and
they were generally established by convention and not as part of the
programming language. Typically, you returned a special value or set a flag,
and the recipient was supposed to look at the value or the flag and determine
that something was amiss. However, as the years passed, it was discovered that
programmers who use a library tend to think of themselves as invincible, as in,
“Yes, errors might happen to others but not in
my
code.” So, not too surprisingly, they wouldn’t check for the error
conditions (and sometimes the error conditions were too silly to check for
[41]).
If you
were
thorough enough to check for an error every time you called a method, your code
could turn into an unreadable nightmare. Because programmers could still coax
systems out of these languages they were resistant to admitting the truth: This
approach to handling errors was a major limitation to creating large, robust,
maintainable programs.
The
solution is to take the casual nature out of error handling and to enforce
formality. This actually has a long history, since implementations of
exception
handling
go back to operating systems in the 1960s and even to BASIC’s
on
error goto
.
But C++ exception handling was based on Ada, and Java’s is based
primarily on C++ (although it looks even more like Object Pascal).
The
word “exception” is meant in the sense of “I take exception
to that.” At the point where the problem occurs you might not know what
to do with it, but you do know that you can’t just continue on merrily;
you must stop and somebody, somewhere, must figure out what to do. But you
don’t have enough information in the current context to fix the problem.
So you hand the problem out to a higher context where someone is qualified to
make the proper decision (much like a chain of command).
The
other rather significant benefit of exceptions is that they clean up error
handling code. Instead of checking for a particular error and dealing with it
at multiple places in your program, you no longer need to check at the point of
the method call (since the exception will guarantee that someone catches it).
And, you need to handle the problem in only one place, the so-called exception
handler
.
This saves you code and it separates the code that describes what you want to
do from the code that is executed when things go awry. In general, reading,
writing, and debugging code becomes much clearer with exceptions than when
using the old way.
Because
exception handling is enforced by the Java compiler, there are only so many
examples that can be written in this book without learning about exception
handling. This chapter introduces you to the code you need to write to properly
handle the exceptions, and the way you can generate your own exceptions if one
of your methods gets into trouble.
[41]
The C programmer can look up the return value of
printf( )
for an example of this.