Handling Errors and Exceptions


Part of your grade is based on how well you handle exceptions. Does your application crash when the user types in an incorrect number? What happens when your remote mechanism doesn't respond? Your evaluator will look closely at how well your code deals with such problems. Listing 17.2 is an example of error handling that demonstrates how errors propagate through the call stack. It represents a DatabaseError class with a general message; this class is instantiated with the specified detail message. This error can be thrown to indicate that the database has failed. Note that the constructors convert the constructor argument to a detailed String message explaining the condition of failure. Last, you can see how the final constructor creates a DatabaseError with a detailed message and nested error. This is an example of how you can nest errors in your application.

Listing 17.2 An Example of Error Handling
 /**  * Thrown to indicate that the database has failed.  *  * These constructors convert an argument to a detail  * String message explaining the condition of failure.  */ public class DatabaseError extends Error {     /**      * Constructs a DatabaseError with no detail message.      */     public DatabaseError()     {     }     /**      * Constructs a DatabaseError with a detail message,      * even if it is a null reference. The public constructors will      * never call this constructor with a null argument.      * @param message value to be used in constructing detail message      */     private DatabaseError(String message)     {         super(message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(Object message)     {         this("" +  message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(boolean message)     {         this("" +  message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(char message)     {         this("" +  message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(int message)     {         this("" +  message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(long message)     {         this("" +  message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(float message)     {         this("" +  message);     }     /**      * Constructs a DatabaseError with its Object message converted      * to a string.      *      * @param message value to be used in constructing detail message      */     public DatabaseError(double message)     {         this("" +  message);     }     /**      * Constructs a <code>DatabaseError</code> with the specified      * detail message and nested error.      *      * @param message the detail message      * @param error the nested error      */     public DatabaseError(String message, Error error)     {         super(message, error);     } } 

The try-catch-finally Construction

The built-in mechanism for handling errors and exceptions is the try-catch-finally construction. Its basic outline is shown in Listing 17.3. Note that the catch conditions start with the most granular or most specific exception first. The try-catch-finally construction then catches less granular or less specific exceptions. Last, it catches the broadest exceptions. If you reverse the order, the first catch is always invoked, as the more specific exceptions are the same type as the more generalized superclass; therefore, using the reverse order is incorrect.

Listing 17.3 An Example of the try-catch-finally Construction
 try {      someOperation(); } catch (LowestException le) {      System.out.println(le); } catch (MiddleException me) {      System.out.println(me); } catch (HighestException he) {      System.out.println(he); } finally {      System.out.println("finally"); } 
graphics/note_icon.gif

The try-catch-finally block is essential for handling exceptions. However, do not overuse this construction. For example, don't use it to catch fatal errors.


The following is how Sun defines the three parts of the try-catch-finally block:

  • try ” Defines a block of statements that might throw an exception.

  • catch ” An optional block of statements that is executed when an exception or a runtime error occurs in a preceding try block.

  • finally ” This block executes regardless of whether an exception occurred in the previous try block.

Listing 17.4 demonstrates how you can propagate an exception through the call stack. It shows you how to control where action is taken in response to an exception. Exceptions have the capability to propagate error reporting up the call stack of methods . In this listing, notice how an exception in myNextMethod() is propagated up into myMethod() and then propagated up into main() .

Listing 17.4 Controlling Exception Catching
 import java.io.IOException; /*  * Notice how an exception in myNextMethod() is propagated  * up into myMethod() and then propagated up into main().  */ public class MyExceptionHandler extends IOException {     static int MAIN_METHOD = 1;     static int MY_METHOD = 2;     static int MY_NEXT_METHOD = 3;     static int CATCH = MY_METHOD; /*  * main() gets an exception that comes from deep within the  * call stack, in this case from myNextMethod().  * @param args command-line arguments  */     public static void main(String[] args)     {         try         {              myMethod();         } catch (IOException ioe)         {              System.out.println("main() - " + ioe);         } finally         {              System.out.println("main() - finally");         }     } /*  * An exception in myMethod() is then propagated up into main().  */     public static void myMethod() throws IOException     {         if(CATCH == MY_METHOD)         {             try             {                  throw new IOException();             } catch (IOException ioe)             {                  System.out.println("myMethod() - " + ioe);             }         } else if(CATCH == MY_NEXT_METHOD)         {             try             {                  myNextMethod();             } catch (IOException ioe)             {                  System.out.println("myMethod() - " + ioe);             }         }     } /*  * An exception in myNextMethod() is propagated  * up into myMethod().  */     public static void myNextMethod() throws IOException     {         if(CATCH == MY_NEXT_METHOD)         {             try             {                  throw new IOException();             } catch (IOException ioe)             {                  System.out.println("myNextMethod() - " + ioe);             }         } else         {              throw new IOException();         }     } } 

In Listing 17.4, you get one of the following three outputs, depending on which setting you assign to the CATCH flag:

 main() - java.io.IOException main() - finally 

or

 myMethod() - java.io.IOException main() - finally 

or

 myNextMethod() - java.io.IOException main()  finally 

Notice that regardless of which setting you assign to the CATCH flag, the finally clause in the try block of the main() method always executes. This is an important consideration when handling RMI or database connections in your solution.

Listing 17.4 shows how to throw an exception as opposed to the JVM throwing one. If you add a custom exception class to your solution, you will likely throw it at some point.



JavaT 2 Developer Exam CramT 2 (Exam CX-310-252A and CX-310-027)
JavaT 2 Developer Exam CramT 2 (Exam CX-310-252A and CX-310-027)
ISBN: N/A
EAN: N/A
Year: 2003
Pages: 187

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net