Propagation of Exception in Java
If an exception occurs within a method in Java, it is first thrown from the top of the stack and if it is not caught there, it moves down the call stack to the method immediately below the current one. Now, if it is not caught there, the exception again moves down to the previous method, and so on until it is caught or until it reaches the bottom-most entry of the call stack. This is called propagation of exception. Basically, Java tries to handle exceptional conditions in a program by using try-catch block.
The following code explains how an exception propagates in a Java program (Except03.java).
public class Except03 {
public static void main(String args[]) {
System.out.println("Within main()");
Except03 ex = new Except03();
try {
ex.divide(); //called method divide()
System.out.println("Division operation"); //never executes
}
catch (ArithmeticException e) {
System.out.println("Exception : " + e);
}
System.out.println("Back to main()");
int result = 100 / 10;
System.out.println("result = " + result);
}
void divide() {
System.out.println("Within divide()");
compute(); //called method compute()
System.out.println("Back to divide()"); //never executes
}
void compute() {
System.out.println("Within compute()");
int value = 10 / 0; //exception occurs here
System.out.println("value: " + value); //never executes
}
}
Output of the above program:
$ java Except03
Within main()
Within divide()
Within compute()
Exception : java.lang.ArithmeticException: / by zero
Back to main()
result = 10
The program works as follows:
The figure below depicts the whole scenario using the call stack of methods.
Figure 3: Call stack of methods for the example program
As seen from the above figure, the program execution begins with the main() method which is having a try-catch block. From main(), within its try block the divide() method gets called. In a similar fashion, from divide(), the compute() method gets called. Now, within compute(), an exception has occurred (java.lang.ArithmeticException: / by zero).
Once an exception is thrown within compute() method, program control transfers (i.e. exception propagates) from this method to the previous method named divide() as there is no try-catch. So, the statement System.out.println(“value: = “+value) inside it never executes.
Similarly, within divide(), the try-catch block is missing. As a result, the exception propagates from this method to its immediate caller which happens to be the main() method without printing this line System.out.println(“Back to divide()”).
Within main(), there is try-catch; so the exception can be handled. Once the catch statement has executed, program control continues with the next line in the program following the entire try-catch mechanism. Here the call to println( ) inside the catch block displays the string representation of the ArithmeticException object e and the println( ) method call following the catch block shows the value of variable result as 10. However, the println() statement within try block of main() never gets printed.
Advantages of Exception Handling
1) Separating error-handling code from regular code
2) Propagating errors up the call stack of methods
3) Grouping and differentiating error types
In the next section we will discuss about multiple catch blocks.