When an exception is thrown in your program, you can find the exact statement in your program that caused the exception to occur by examining the lines that are displayed right after the line that indicates which exception was encountered. These lines of information that are displayed when an exception occurs is known as Stack trace. It lists the different methods that the exception passed through before your program was completely aborted. Each line in the stack trace contains not only the method name and the corresponding classname but also the name of the source file that contains the class and the line number where the exception occurred.
Let us consider the following program
public class StackTrace { static void B() { int x = 12 ; int y = 0 ; int z = x/y; } static void A() { B(); } public static void main(String[] args) { A(); } }
The following program on execution displays the following lines of output
The first line of the stack trace specifies that an ArithmeticExeption has occurred. The text after the name of the exception, / by zero indicates that this exception occurred as a result of an attempt to divide by zero.
Starting from the last line of the stack trace, we see that the exception was detected in line 15 of the main ()method. Each line of the stack trace contains the classname and the method name followed by the filename and line number.
StackTrace.main (StackTrace.java:15)
Moving up the stack trace, you see that the exception occurred at line 11 in the A () method of the StackTrace class. The top row of the call chain indicates that the method B () actually throws the exception ArithmeticExeption.
Being acquainted with stack trace, we shall now understand how exceptions are handled in multiple method call invocations. In order to understand it, let as modify the previous program as follows,
public class ModifiedStackTrace { static void B() { int x = 12 ; int y = 0 ; int z =x/y; System.out.println("z="+z); } static void A() { B(); } public static void main(String[] args) { try { A(); } catch(ArithmeticException e) { System.out.println("Integer Division by 0 not Possible,Try Again\n"); System.out.println("Stack Trace Information...\n"); e.printStackTrace(); } } }
In the above example, the main () method invokes method A( ) . The method A( ) invokes method B() where on execution of the statement,
The java.lang.ArithmeticException exception is raised as integer division by 0 is not possible. So the JVM starts the process of finding the catch block that handles the exception. The JVM first looks for a matching catch block within the current method i.e.B () . As it is unable to find it, so the method B() is aborted and the control is returned to the calling method A() . The JVM again looks for a matching catch block within the current method i.e. A( ) . As it again fails to find the matching catch block so method A() is aborted and the control is returned to the calling method main () . The JVM again looks for the catch block and as it finds one so it is executed. So we see that when multiple method invocations are involved, the JVM looks for the appropriate catch block by propagating the exceptions backward through a chain of method calls, starting from the method in which the exception was raised. This can be seen from the stack trace information.