Exception propagation in Java occurs when an exception thrown from the top of the stack. If not caught there, the exception again drops down to the previous method, and so on until caught or reach the very bottom of call stack. The list of method invocations is known as the call stack and the method of searching exception handler is called Exception Propagation.
If it don’t find exception handler till the bottom of the call stack, then exception will get handover to ‘default exception handler’.
Note that both checked and unchecked exception will get propagated if they don’t get handled in the method they raised.
Declare exception(with throws keyword) is different and Exception propagation is different. Declaration is useful at compile time to inform the caller. Exception propagation happens at runtime, It is the process of searching exception handler.
Example 01 : unchecked exception propagation – without exception declaration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.vidvaan.corejava.exception19.exception.propagation; //unchecked exception propagation - without exception declaration public class Example01ExceptionPropagation { public void method1() { int result = 5 / 0; // exception propagated to method2() } public void method2() { method1(); // exception propagated to method3() } public void method3() { try { method2(); // if not handled here exception propagated to main() method } catch (ArithmeticException e) { System.out.println("exception handled"); } } public static void main(String args[]) { // // if not handled in main() method exception propagated to // defaultExceptionHandler System.out.println("main() begin"); Example01ExceptionPropagation obj = new Example01ExceptionPropagation(); obj.method3(); System.out.println("main() end"); } } |
Output :
main() begin
exception handled
main() end
In the above example, ArithmeticException raised in method1(). As it is not handled there then it is propagated to method2(). And we can see that method2() also not handled ArithmeticException. So it is again propagated to method3(). We can see that in method3() it got handled. This is the way exception propagation happens from the method where exception raised to the caller method.
Example 02 : unchecked exception propagation – with exception declaration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.vidvaan.corejava.exception07.throwskeyword; //unchecked exception propagation - with exception declaration public class Example02ExceptionPropagation { // declaring that there would be chance of ArithmeticException if some one calls // this method public void method1() throws ArithmeticException { int result = 1 / 0; // exception propagated to method2() } // declaring that there would be chance of ArithmeticException if some one calls // this method public void method2() throws ArithmeticException { method1(); // exception propagated to method3() } public void method3() { try { method2(); // if not handled here exception propagated to main() method } catch (ArithmeticException e) { System.out.println("exception handled"); } } public static void main(String args[]) { // // if not handled in main() method exception propagated to // defaultExceptionHandler System.out.println("main() begin"); Example01ExceptionPropagation obj = new Example01ExceptionPropagation(); obj.method3(); System.out.println("main() end"); } } |
Output :
main() begin
exception handled
main() end
In the above example, we are declaring in method1() and method2() signatures saying that, there would be chance of throwing ArithmeticException when some one calls these methods.
As these methods declared unchecked exceptions there won’t be any change required in the code of caller method.
Note that ‘declaring exception’ is different and ‘exception propagation’ is different. Here whether we declare the exception or not, exception propagation happens in the same way.
Example 03 : unchecked exception propagation – default exception handler
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.vidvaan.corejava.exception19.exception.propagation; //unchecked exception propagation - default exception handler public class Example03ExceptionPropagation { // declaring that there would be chance of ArithmeticException if some one calls // this method public void method1() throws ArithmeticException { int result = 1 / 0; // exception propagated to method2() } // declaring that there would be chance of ArithmeticException if some one calls // this method public void method2() throws ArithmeticException { method1(); // exception propagated to method3() } // declaring that there would be chance of ArithmeticException if some one calls // this method public void method3() throws ArithmeticException { method2(); // exception propagated to main() method } // declaring that there would be chance of ArithmeticException // As it is main method, if exception raised, it will handover to default // exception handler public static void main(String args[]) throws ArithmeticException { System.out.println("main() begin"); Example03ExceptionPropagation obj = new Example03ExceptionPropagation(); obj.method3(); // exception not handled in main() method exception propagated to // defaultExceptionHandler System.out.println("main() end"); } } |
Output:
main() begin
Exception in thread “main” java.lang.ArithmeticException: / by zero
at com.vidvaan.corejava.exception19.exception.propagation.Example03ExceptionPropagation.method1(Example03ExceptionPropagation.java:9)
at com.vidvaan.corejava.exception19.exception.propagation.Example03ExceptionPropagation.method2(Example03ExceptionPropagation.java:16)
at com.vidvaan.corejava.exception19.exception.propagation.Example03ExceptionPropagation.method3(Example03ExceptionPropagation.java:23)
at com.vidvaan.corejava.exception19.exception.propagation.Example03ExceptionPropagation.main(Example03ExceptionPropagation.java:33)
In the above example, we are declaring exception on method1(), method2(), method3() and main() method. If exception raised that will be hand over to ‘default exception handler‘.
Example 04 : checked exception propagation – no exception declaration – Compilation error
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.vidvaan.corejava.exception19.exception.propagation; import java.io.IOException; //checked exception propagation - no exception declaration // Compilation Error public class Example04ExceptionPropagation { // method not declared exception public void method1() { System.out.println("Reading File ...something wrong"); throw new IOException("File Reading fail !!!"); // Compilation Error : Unhandled exception type IOException } public void method2() { method1(); // exception propagated to method3() } public void method3() { try { method2(); // if not handled here exception propagated to main() method } catch (ArithmeticException e) { System.out.println("exception handled"); } } public static void main(String args[]) { // // if not handled in main() method exception propagated to // defaultExceptionHandler System.out.println("main() begin"); Example01ExceptionPropagation obj = new Example01ExceptionPropagation(); obj.method3(); System.out.println("main() end"); } } |
Compilation Error :
Unhandled exception type IOException
In the above example, we are getting compilation error in method1(). As it is throwing checked exception the rule is, weather we have to handle it or we need to declare that exception. In the next example we will declare checked exception.
Example 05 : checked exception propagation – with exception declaration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
package com.vidvaan.corejava.exception19.exception.propagation; import java.io.IOException; //checked exception propagation - exception declaration public class Example05ExceptionPropagation { // declaring that there would be chance of IOException if some one calls // this method public void method1() throws IOException { System.out.println("Reading File ...something wrong"); throw new IOException("File Reading fail !!!"); // exception propagated to method2() } // declaring that there would be chance of IOException if some one calls // this method public void method2() throws IOException { method1(); // exception propagated to method3() } public void method3() { try { method2(); // if not handled here exception propagated to main() method } catch (IOException e) { System.out.println("exception handled"); } } public static void main(String args[]) { System.out.println("main() begin"); Example01ExceptionPropagation obj = new Example01ExceptionPropagation(); obj.method3(); System.out.println("main() end"); } } |
Output :
main() begin
exception handled
main() end
In the above example, we declared checked exception on method1(), method2() signature and we handled checked exception in method3().
So both checked and unchecked exceptions are propagated to caller method if they don’t handled. So the propagation continued until it found exception handler, If it never found exception handler it will handover exception to ‘default exception handler’.