Last week we began to thoroughly explain exceptions in Java. This week, we're going to press a bit further and explain some of the details of exception use. Don't be fooled into thinking this isn't an important subject; exceptions can come into play while using some of the simplest of standard Java classes, and Java will force you to handle them properly, one way or another. Runtime Exceptions
We explained in the last column that exceptions work by propagating up the call stack; in other words, checking the current method, and then the methods that called it, all the way back up to the top layer (the method that was first invoked) for an exception handler.
In theory, if an exception cannot find an exception handler that can handle it, your entire program stops. But as we hinted last week, this is very unlikely for your Java applets. Why? Because Java wants to encourage you to be a good programmer, and good programmers always catch and deal with any exception that might be thrown.
The simple mechanism that makes this work is as follows: Every method that throws an exception must either also catch the exception, or indicate explicitly that its exception will continue up the call stack to the invoking method. In other words, if you plan to call a method B from within method A, and method B is declared to throw an exception of some type, method A must then be able to handle it, or pass it on again itself, and so on.
public void B() throws OurException { ... throw OurException; ... } public void A() { ... try { B(); } catch (OurException oe) { ... } ... }
You can see here that the declaration of method B includes the statement"throws OurException". In order for this code to compile with a Java compiler, method A must either tryB()and catchOurException(which it does), or it must itself declare"throws OurException"and whoever might invokeA()then inherits this dilemma.As an applet author, you'll most likely encounter exceptions first by using some predefined method given in the Java API standard, which throws an exception of some kind. If you're used to programming in C or C++, imagine that where prevously your standard library functions returned NULL or -1, now they may throw one or more exceptions (which must be handled in some fashion). To Java engineers, what exceptions may be thrown by a method (and thus, in some cases, the number of things that may go wrong during its invocation) are a part of the method's interface--which is just as important as the name of the method and the kinds of parameters that it takes.
With this mechanism in place, we are effectively forced to never take shortcuts with error checking.
javacwill simply refuse to work if we don't at least make the motions of handling error conditions. However, as mentioned earlier, there is an entire subclass of exceptions that are exempt from this requirement--"Runtime Exceptions."The Runtime Exception class was created because there were a number of error conditions that, for consistency's sake, would cause an exception to be thrown; however, requiring a handler at each point where they might occur would be completely impossible. These basic errors are detected by the runtime system itself such as division by zero, or asking for the tenth element of a five-element array. Since these errors would make it possible for just about any piece of Java code to throw an exception (theoretically), the exceptions associated with these errors are made "Runtime Exceptions"--and thus exempt from the policy we've been discussing.
Note that, should you one day need to design your own class of exception objects, there is nothing to stop you, the programmer, from creating your own subclasses of RuntimeException that would also be exempt. The Java documentation, however, advises against it. Naturally, there are inherent benefits in having your language forcing its users to be thorough.
Next week, we'll have the final wrap-up on Exceptions--the vagaries of the "try-catch-finally" exception handler and the use of inheritance in exception classes. Stay tuned.