printStackTrace, getStackTrace and getMessage
Recall from Section 13.6 that exceptions derive from class Throwable. Class Throwable offers a printStackTrace method that outputs to the standard error stream the stack trace (discussed in Section 13.3). Often, this is helpful in testing and debugging. Class Throwable also provides a getStackTrace method that retrieves stack-trace information that might be printed by printStackTrace. Class Throwable's getMessage method returns the descriptive string stored in an exception. The example in this section demonstrates these three methods.
Error-Prevention Tip 13.10
An exception that is not caught in an application causes Java's default exception handler to run. This displays the name of the exception, a descriptive message that indicates the problem that occurred and a complete execution stack trace. |
Error-Prevention Tip 13.11
Throwable method toString (inherited by all THRowable subclasses) returns a string containing the name of the exception's class and a descriptive message. |
Figure 13.7 demonstrates getMessage, printStackTrace and getStackTrace. If we wanted to output the stack-trace information to streams other than the standard error stream, we could use the information returned from getStackTrace, and output this data to another stream. You will learn about sending data to other streams in Chapter 14, Files and Streams.
Figure 13.7. Throwable methods getMessage, getStackTrace and printStackTrace.
(This item is displayed on pages 659 - 660 in the print version)
1 // Fig. 13.7: UsingExceptions.java 2 // Demonstrating getMessage and printStackTrace from class Exception. 3 4 public class UsingExceptions 5 { 6 public static void main( String args[] ) 7 { 8 try 9 { 10 method1(); // call method1 11 } // end try 12 catch ( Exception exception ) // catch exception thrown in method1 13 { 14 System.err.printf( "%s ", exception.getMessage() ); 15 exception.printStackTrace(); // print exception stack trace 16 17 // obtain the stack-trace information 18 StackTraceElement[] traceElements = exception.getStackTrace(); 19 20 System.out.println( " Stack trace from getStackTrace:" ); 21 System.out.println( "Class File Line Method" ); 22 23 // loop through traceElements to get exception description 24 for ( StackTraceElement element : traceElements ) 25 { 26 System.out.printf( "%s ", element.getClassName() ); 27 System.out.printf( "%s ", element.getFileName() ); 28 System.out.printf( "%s ", element.getLineNumber() ); 29 System.out.printf( "%s ", element.getMethodName() ); 30 } // end for 31 } // end catch 32 } // end main 33 34 // call method2; throw exceptions back to main 35 public static void method1() throws Exception 36 { 37 method2(); 38 } // end method method1 39 40 // call method3; throw exceptions back to method1 41 public static void method2() throws Exception 42 { 43 method3(); 44 } // end method method2 45 46 // throw Exception back to method2 47 public static void method3() throws Exception 48 { 49 throw new Exception( "Exception thrown in method3" ); 50 } // end method method3 51 } // end class UsingExceptions
|
In main, the TRy block (lines 811) calls method1 (declared at lines 3538). Next, method1 calls method2 (declared at lines 4144), which in turn calls method3 (declared at lines 4750). Line 49 of method3 throws an Exception objectthis is the throw point. Because throw statement at line 49 is not enclosed in a TRy block, stack unwinding occursmethod3 terminates at line 49, then returns control to the statement in method2 that invoked method3 (i.e., line 43). Because no try block encloses line 43, stack unwinding occurs againmethod2 terminates at line 43 and returns control to the statement in method1 that invoked method2 (i.e., line 37). Because no TRy block encloses line 37, stack unwinding occurs one more timemethod1 terminates at line 37 and returns control to the statement in main that invoked method1 (i.e., line 10). The try block at lines 811 encloses this statement. The exception has not been handled, so the TRy block terminates and the first matching catch block (lines 1231) catches and processes the exception.
Line 14 invokes the exception's getMessage method to get the exception description. Line 15 invokes the exception's printStackTrace method to output the stack trace that indicates where the exception occurred. Line 18 invokes the exception's getStackTrace method to obtain the stack-trace information as an array of StackTraceElement objects. Lines 2430 get each StackTraceElement in the array and invoke its methods getClassName, getFileName, getLineNumber and getMethodName to get the class name, file name, line number and method name, respectively, for that StackTraceElement. Each Stack-TraceElement represents one method call on the method-call stack.
The output in Fig. 13.7 shows that the stack-trace information printed by printStackTrace follows the pattern: className.methodName(fileName:lineNumber), where className, methodName and fileName indicate the names of the class, method and file in which the exception occurred, respectively, and the lineNumber indicates where in the file the exception occurred. You saw this in the output for Fig. 13.1. Method getStackTrace enables custom processing of the exception information. Compare the output of printStackTrace with the output created from the StackTraceElements to see that both contain the same stack-trace information.
Software Engineering Observation 13.12
Never ignore an exception you catch. At least use printStackTrace to output an error message. This will inform users that a problem exists, so that they can take appropriate actions. |