Alternative approaches
An exception-handling system is a trap door that allows your program to abandon execution of the normal sequence of statements. The trap door is used when an exceptional condition occurs, such that normal execution is no longer possible or desirable. Exceptions represent conditions that the current method is unable to handle. The reason exception handling systems were developed is because the approach of dealing with each possible error condition produced by each function call was too onerous, and programmers simply werent doing it. As a result, they were ignoring the errors. Its worth observing that the issue of programmer convenience in handling errors was a prime motivation for exceptions in the first place.
One of the important guidelines in exception handling is dont catch an exception unless you know what to do with it. In fact, one of the important goals of exception handling is to move the error-handling code away from the point where the errors occur. This allows you to focus on what you want to accomplish in one section of your code, and how youre going to deal with problems in a distinct separate section of your code. As a result, your mainline code is not cluttered with error-handling logic, and its much easier to understand and maintain.
Checked exceptions complicate this scenario a bit, because they force you to add catch clauses in places where you may not be ready to handle an error. This results in the harmful if swallowed problem:
try {
// ... to do something useful
} catch(ObligatoryException e) {} // Gulp!
Programmers (myself included, in the first edition of this book) would just do the simplest thing, and swallow the exceptionoften unintentionally, but once you do it, the compiler has been satisfied, so unless you remember to revisit and correct the code, the exception will be lost. The exception happens, but it vanishes completely when swallowed. Because the compiler forces you to write code right away to handle the exception, this seems like the easiest solution even though its probably the worst thing you can do.
Horrified upon realizing that I had done this, in the second edition I fixed the problem by printing the stack trace inside the handler (as is still seenappropriatelyin a number of examples in this chapter). While this is useful to trace the behavior of exceptions, it still indicates that you dont really know what to do with the exception at that point in your code. In this section well look at some of the issues and complications arising from checked exceptions, and options that you have when dealing with them.
This topic seems simple. But it is not only complicated, it is also an issue of some volatility. There are people who are staunchly rooted on either side of the fence and who feel that the correct answer (theirs) is blatantly obvious. I believe the reason for one of these positions is the distinct benefit seen in going from a poorly-typed language like pre-ANSI C to a strong, statically-typed language (that is, checked at compile-time) like C++ or Java. When you make that transition (as I did), the benefits are so dramatic that it can seem like strong static type checking is always the best answer to most problems. My hope is to relate a little bit of my own evolution, that has brought the absolute value of strong static type checking into question; clearly, its very helpful much of the time, but theres a fuzzy line we cross when it begins to get in the way and become a hindrance (one of my favorite quotes is: All models are wrong. Some are useful.).