Handling Errors using Exceptions |
Because the Java language does not require methods to catch or declare runtime exceptions, it's tempting for programmers to write code that throws only runtime exceptions or make all of their exception subclasses inherit from RuntimeException. Both of these programming shortcuts allow programmers to write Java code without bothering with all of the naggingerrors from the compiler and without bothering to declare or catch any exceptions. While this may seem convenient to the programmer, it sidesteps the intent of Java's catch or declare requirement and can cause problems for the programmers using your classes.InputFile.java:8: Warning: Exception java.io.FileNotFoundException must be caught, or it must be declared in throws clause of this method. fis = new FileInputStream(filename); ^Why did the Java designers decide to force a method to declare all uncaught non-runtime exceptions that can be thrown within its scope? Because any exception that can be thrown by a method is really part of the method's public programming interface: callers of a method must know about the exceptions that a method can throw in order to intelligently and conciously decide what to do about those exceptions. The exceptions that a method can throw are as much a part of that method's programming interface as its parameters and return value.
Your next question might be: "Well then, if it's so good to document a method's API including the exceptions that it can throw, why not declare runtime exceptions, too?"
RuntimeExceptions represent a programming problem that was detected by the runtime system or an inappropriate use of an API. This includes arithmetic exceptions, such as when dividing by zero, pointer exceptions, such as trying to access an object through a null reference, and indexing exceptions, such as attempting to access an array element through an index that is too large or too small.
Runtime exceptions can occur anywhere in a program and in a typical program can be very numerous. Typically, the cost of checking for runtime exceptions exceeds the benefit of catching or declaring them. Thus the compiler does not require that you catch or declare runtime exceptions, though you can.
Non-runtime exceptions represent useful information about the operation of a legally specified request that the caller may have had no control over and that the caller needs to be informed about--for example, the filesystem is now full, or the remote end has closed the connection, or the access privileges don't allow this action.
What does it buy you if you throw a RuntimeException or create a subclass of RuntimeException just because you don't want to deal with declaring it? Simply, you get the ability to throw an exception without declaring that you do so. In other words, it is a way to avoid documenting the exceptions that a method can throw. When is this good? Well, when is it ever good to avoid documenting a method's behavior? The answer is "hardly ever".
Rules of Thumb:
- A method can detect and throw a RuntimeException when it's encountered an error in the virtual machine runtime, however, it's typically easier to just let the virtual machine detect and throw it. Normally, the methods you write should throw an Exception.
- Similarly, you create a subclass of RuntimeException when you are creating an error in the virtual machine runtime (which you probably aren't). Otherwise you should subclass Exception.
- Do not throw a runtime exception or create a subclass of RuntimeException simply because you don't want to be bothered with declaring them.
Handling Errors using Exceptions |