|
The proper use of exceptions can make your programs easier to develop and maintain, freer from bugs, and simpler to use. When exceptions are misused, the opposite situation prevails: programs perform poorly, confuse users, and are harder to maintain. To protect against these problems, this series will provide valuable exception-handling techniques. In Part 1, I look at the challenges of using exceptions effectively, and offer guidelines on properly incorporating error handling into your classes at design time. You should think about exceptions and error recovery during the design phase, not after development is complete. Using exceptions correctly entails looking at error conditions from several perspectives -- from the perspectives of the class that throws the error, the classes that catch the exception, and the poor user who has to deal with the results. To write friendly programs, you must consider error conditions from all these points of view. Consider this simple exception class and a method that throws it:
When the
Each piece of information will prove important to different recipients. The exception type is important primarily to the classes that called When you throw an exception, you should ensure that all recipients receive the information they need to proceed effectively. That means you should throw an exception of the right exception class so that callers can take the appropriate corrective action, and you should generate useful diagnostic messages for users so that they can understand what happened if the program doesn't handle the exception. Write Sensible Throws Clauses
The set of exception types thrown by a method is an important element of a class's design. When writing a
It's unwise to simply declare a method as throwing all the exceptions that might be thrown by methods it calls. Not only is this an abdication of design responsibility, but it exposes a method's implementation as part of its interface, limiting your ability to modify the implementation in the future. For example, suppose the
There is no hard-and-fast rule about how many exception types a method should throw, but fewer is generally better. Each exception type a method might throw will have to either be caught or thrown by any method that calls it, so the more different types of exceptions a method throws, the more difficult that method will be to use. If you throw too many exception types, callers might get lazy and simply catch
When writing a Make Your Throws Clauses Stable
There is another significant advantage to throwing a small number of higher-level exception types instead of many individual low-level exception types: it prevents the
When method signatures change, they often trigger modifications in classes that call them. The impact of those modifications can range from mildly annoying to disastrously inconvenient, depending on how many classes must change and on how many different people or organizations use the altered class. The
Instead of adding a new exception class to a method's
Subclassing exceptions from a common parent allows exception handling to proceed in a more object-oriented manner. Callers can choose to treat all IO-related exceptions equally with a single
Grouping exception types particular to a package or application together by subclassing them from a common parent improves the stability of methods' What to Do with Exceptions You Don't Want to ThrowWhen your code encounters a low-level exception whose type information would not be meaningful to your callers, translate the exception into one that makes more sense. For example:
Now, both the program and the user receive the information they need. The caller learns that the resource could not load; this likely provides a more useful type of error than the underlying
You can extend the above technique by providing an alternate constructor for Don't Forget the UserThough the program doesn't care what text you place in the exception message (and programs should never look at the exception message text and use it to determine what happened), the user does. Error messages should be meaningful both to developers (so they can know more about the error's source and cause) and to users (so they have an inkling of why the program failed). Error messages like "Bad index value" or "Error in initialization" offer no help. In order to ensure that users understand error messages, you also should think about who those users might be. Will they all speak the same language as the developer? If not, you should use an appropriate method for loading error message strings or templates from some localization mechanism, such as resource bundles, so that error messages can be easily translated into other languages without any text editing. You should avoid hardcoding English text strings into your code if your classes will eventually be localized for other languages. In fact, even in the absence of a localization requirement, for a number of reasons it's a good idea to get error message strings out of an error catalog or resource bundle and then construct them on the fly. For instance, an exhaustive catalog of all error messages a program might throw will likely make it easier to document your program. The documentation writer can use the catalog as a starting point for writing comprehensive documentation. Use Exceptions ProperlyProper exception handling is critically important; but, unfortunately, the ways in which an application or class library generates and handles exceptions is one of the most ignored aspects of program design. Good exception handling practices don't just make your programs more robust and easier to maintain; when something bad happens, the thrown exception might provide the only clue as to what went wrong. If your programs use exceptions sensibly and generate meaningful error messages, the user is less likely to grow more confused and annoyed (at a time when your program has failed, and the user is probably already annoyed). Good exception handling will also make your support staff better able to understand a problem and fix it. Properly using exceptions ensures that all parties -- code and humans alike -- have the error-recovery information they need.
Reprinted with permission from the August 2001 edition of JavaWorld magazine. Copyright Web Publishing Inc., an IDG Communications company. Register for editorial e-mail alerts. About the AuthorBrian Goetz is a software consultant who has been developing software professionally for more than 15 years. He is a principal consultant at Quiotix, a software development and consulting firm located in Los Altos, Calif. | ||||||||
|
| ||||||||||||