When an exception occurs, there are several general ways to handle them.
Here is a simple example. It calls a couple of methods, then tries to divide 1 by 0.
public class stktrace { public static void method1() { method2(); } public static void method2() { System.out.println("method2"); int a = 1/0; } // method2 public static void main(String[] args) { System.out.println("Calling the first method"); method1(); System.out.println("Done calling the first method"); } // main } // class stktrace
Calling the first method method2 Exception in thread "main" java.lang.ArithmeticException: / by zero at stktrace.method2(stktrace.java:7) at stktrace.method1(stktrace.java:3) at stktrace.main(stktrace.java:13)The line starting with the word "Exception" contains the error message. The other lines are the stack trace. the first "at" line shows that the error occurred in method2() at line 7 of the file. The next line shows that method2() was called from method1() at line 3 and finally, method1() got called from main() at line 13. Also note that the print statement after the call to method1() in main() never got executed. Once the exception occurred, all other processing stopped.
Now, let's handle the exception. In this case, there is very little we can actually do but we can print a more meaningful message and exit nicely.
public class stktrace { public static void method1() { method2(); } public static void method2() { System.out.println("method2"); int a = 1/0; } // method2 public static void main(String[] args) { System.out.println("Calling the first method"); try { method1(); } catch(ArithmeticException a) { System.out.println("Arithmetic problem, stopping"); System.out.println("System message was '"+ a.getMessage() + "'"); System.out.println("and here is how we got here"); a.printStackTrace(); System.exit(1); } // catch System.out.println("Done calling the first method"); } // main } // class stktrace
Calling the first method method2 Arithmetic problem, stopping System message was '/ by zero' and here is how we got here java.lang.ArithmeticException: / by zero at stktrace.method2(stktrace.java:7) at stktrace.method1(stktrace.java:3) at stktrace.main(stktrace.java:14)
Exceptions can be handled locally, as in the examples above. Or they can be passed on to a higher level. This code, from the examples (Listing 8.3-4) show how this can be done.
//******************************************************************** // Propagation.java Author: Lewis and Loftus // // Demonstrates exception propagation. //******************************************************************** public class Propagation { //----------------------------------------------------------------- // Invokes the level1 method to begin the exception demonstration. //----------------------------------------------------------------- static public void main (String[] args) { ExceptionScope demo = new ExceptionScope(); System.out.println("Program beginning."); demo.level1(); System.out.println("Program ending."); } } //******************************************************************** // ExceptionScope.java Author: Lewis and Loftus // // Demonstrates exception propagation. //******************************************************************** public class ExceptionScope { //----------------------------------------------------------------- // Catches and handles the exception that is thrown in level3. //----------------------------------------------------------------- public void level1() { System.out.println("Level 1 beginning."); try { level2(); } catch (ArithmeticException problem) { System.out.println (); System.out.println ("The exception message is: " + problem.getMessage()); System.out.println (); System.out.println ("The call stack trace:"); problem.printStackTrace(); System.out.println (); } System.out.println("Level 1 ending."); } //----------------------------------------------------------------- // Serves as an intermediate level. The exception propagates // through this method back to level1. //----------------------------------------------------------------- public void level2() { System.out.println("Level 2 beginning."); level3 (); System.out.println("Level 2 ending."); } //----------------------------------------------------------------- // Performs a calculation to produce an exception. It is not // caught and handled at this level. //----------------------------------------------------------------- public void level3 () { int numerator = 10, denominator = 0; System.out.println("Level 3 beginning."); int result = numerator / denominator; System.out.println("Level 3 ending."); } }There is an exception hierarchy, like there is a class hierarchy. Some of the entries can be seem on page 387. You can create your own exception by creating classes that extend the Exception class.
// this is our exception. We use the parent classes // constructor method. Then we print our message. public class baddivision extends Exception { baddivision(String message) { super(message); System.out.println("Division problem, stopping"); } } // badDivisionThis class does the arithmetic and causes and catches the exception.
// this performs a division operation on the arguments. // It catches the builtin exception and throws its own. public class helper { public int method1(int numer,int denom) throws baddivision { System.out.println("method1"); try { return numer/denom; } catch(ArithmeticException a) { throw new baddivision("can't divide " + numer + " by " + denom); } // catch } // method1 } // class helperThen the main class that tests the others.
// this is the test code for the exception example public class exc1 { public static void main(String[] args) { int c=-1; System.out.println("Calling the method with args that should work"); helper h = new helper(); try { c = h.method1(10,3); } catch(baddivision b) { System.out.println("System message was '"+ b.getMessage() + "'"); System.exit(1); } // catch System.out.println("c = " + c); System.out.println("Done calling the method with args that should work"); System.out.println("Calling the method with args that should fail"); try { c = h.method1(10,0); // this will divide by 0 } catch(baddivision b) { System.out.println("System message was '"+ b.getMessage() + "'"); System.exit(1); } // catch // we should never see these messages System.out.println("c = " + c); System.out.println("Done calling the method with args that should fail"); } // main } // class exc1The output looks like this.
Calling the method with args that should work method2 c = 3 Done calling the method with args that should work Calling the method with args that should fail method2 Division problem, stopping System message was 'can't divide 10 by 0'This code can also be found here. Note the definition of method1() has a throws clause at the end. This lists the exceptions that this method may throw. The compiler will tell you if you need one and don't have it.