In this article, we will discuss valid & invalid scenarios for returning a value when method is enclosed with try-catch-finally blocks
General rule:
Whenever return-type of method is defined in a method signature, then compulsorily that method has to return value of that type. Like,
- If return-type is defined as “int” data-type, then respective method has to return a value of “int” data-type
- If return-type is defined as object of some class is defined, then corresponding reference-type has to be returned from that method
- Otherwise, compile-time error will be thrown stating “This method must return a result of type <data-type>”
Solution:
- To fix this compile-time error –> provide return statement with some value
ReturnValueExample.java
package in.bench.resources.exception.handling; public class ReturnValueExample { public static void main(String[] args) { calculate(); } public static int calculate() { return 0; } }
Q) Whatever we discussed till now is for simple case, but what if method is enclosed with try-catch-finally block ?
- In the above example, there is no possibility of raising any exception as it contains just single statement for returning value from method
- But if method contains a code which possibly might raise exception during execution, then we need to surround that code with try-catch block for exception handling
- Also, if that method returns a value, then we need to find a way to return value from that particular method involving try-catch block
- For example, consider below program
ReturnValueExample.java
package in.bench.resources.exception.handling; public class ReturnValueExample { public static void main(String[] args) { // invoking static method returnValueFromMethod(); } public static int returnValueFromMethod() { int result = 18/0; return result; } }
Output:
Exception in thread "main" java.lang.ArithmeticException:/ by zero at in.bench.resources.exception.handling.ReturnValueExample .returnValueFromMethod(ReturnValueExample.java:13) at in.bench.resources.exception.handling.ReturnValueExample .main(ReturnValueExample.java:8)
Explanation:
- Above method throws exception during execution
- and terminates program abnormally
- because there is no try-catch block for exception handling
- Therefore, program execute unsuccessfully by throwing exception & terminates abnormally
try-catch block:
- Let us go for the improved version with try-catch-finally blocks,
Problem:
- But here the problem is, from where we need to return value
- In previous program, we had only one loop that is method loop
- i.e.; curly braces start right after method declaration and ends after some statements
Loops in above program:
Here, in the above example as shown in the screen-capture, we have 4 loops i.e.;
- method loop
- try-block loop
- catch-block loop
- finally-block loop
Q) Again, from where we need to return value for this method ?
- There are numerous cases to return value for valid scenarios, let’s go for each case with an example
Valid Cases:
Case 1: write return statement after completion of try-catch-finally blocks; that is just before end of method
Reason:
- This is valid case because after try-catch-finally block execution, method returns value
- Also, it can be seen as 2 independent entities with,
- 1st being try-catch-finally block
- 2nd is return statement after try-catch-finally block
Case 2: write return statement inside finally-block only; but there shouldn’t be any statement after finally-block
Reason:
- whether any exception is raised or NOT from try-block
- and its corresponding exception is being handled or NOT in the catch-block
- finally-block will always be executed irrespective of the program’s outcome
- except in one scenario when System.exit(0); is invoked explicitly
- Error-scenario : any statement after finally block will result in compile-time error stating “Unreachable code”
Case 3: write return statement inside both try-block & catch-block; there is no compulsion to write return inside finally-block and this completely optional (Case 6)
Reason:
- Whenever try-block executes successfully, then it can return value for this method
- Also, if any exception is raised from try-block then its corresponding exception will be caught in the catch-block
- And from catch-block also, it can return value for this method
- Error-scenario : any statement after finally block in this example, will result in compile-time error stating “Unreachable code”
Case 4.A: write return statement inside try-block & at the end of method; that is just before end of method
Reason:
- Whenever try-block executes successfully, then it can always return value for this method
- But if any exception is raised & it is handled in the corresponding catch-block –> return statement at the end of method will be executed and returns the value for this method after executing finally-block
- Error-scenario : any statement after return statement at the end of method, will result in compile-time error stating “Unreachable code”
Case 4.B: write return statement inside both try-block & finally-block; but no statement after finally block
Reason:
- Whenever try-block executes successfully, then it can always return value for this method
- But if any exception is raised & it is handled in the corresponding catch-block –> return statement inside finally-block will return value for this method (after executing any statement inside finally-block before encountering return statement)
- Error-scenario : any statement after return statement (i.e.; finally-block in this case) will result in compile-time error stating “Unreachable code”
Case 4.C: write return statement inside both try-block & finally-block; but no statement after finally block (no catch block for this case)
Reason:
- This case is very similar to Case 4.B but it has got no catch block in try-catch-finally blocks sequence
- So, whenever try-block executes successfully, then it can always return value for this method from try-block
- But if any exception is raised then it is NOT handled as there is no catch-block for this case
- So, whenever exception is raised then JVM checks for handler-code up in the runtime stack & finally-block gets executed to return value (after executing any statement inside finally-block before encountering return statement)
- Error-scenario : any statement after return statement (i.e.; finally-block in this case) will result in compile-time error stating “Unreachable code”
Case 5.A: write return statement inside catch-block & at the end of method; that is just before end of method
Reason:
- Whenever try-block executes successfully, then it can always return value from end of method
- If any exception is raised from try-block then it get caught in the corresponding catch-block and catch-block can also return value
- But if any exception is raised & it is handled in the corresponding catch-block –> return statement at the end of method will be executed and returns value for this method after executing finally-block
- Error-scenario : any statement after return statement at the end of method, will result in compile-time error stating “Unreachable code”
Case 5.B: write return statement inside both catch-block & finally-block; but no statement after finally-block
Reason:
- Whenever try-block executes successfully, then it can always return value from finally-block
- If any exception is raised from try-block then it is get caught in the corresponding catch-block and catch-block can also returns value
- But if any exception is raised & it is handled in the corresponding catch-block –> return statement inside finally-block will return value for this method (after executing any statement inside finally-block before encountering return statement)
- Error-scenario : any statement after return statement (i.e.; finally-block) will result in compile-time error stating “Unreachable code”
Case 6: write return statement inside try-block & catch-block & finally-block; but return value from try-block or catch-block will be overridden by return statement in the finally-block
Reason:
- Whenever try-block executes successfully, then it can return value for this method from try-block
- Similarly, if any exception is raised then exception gets caught in the catch-block & it can also return value (from catch-block)
- Since, we have finally-block returning value therefore returning value from try-block or catch-block will be overridden by return statement in the finally-block
- Because, on all cases finally-block gets executed irrespective of exception is raised or NOT from try-block and it is handled or NOT inside catch-block.
- Therefore, overrides any return value from try-block or catch-block
- This is called overridden case
- Error-scenario : any statement after finally block in this example, will result in compile-time error stating “Unreachable code”
Conclusion for Valid case:
- Above 9 examples are valid cases to write return statement;
- except these 9 example mentioned in the above cases, all other cases results in compile-time error
- following examples depicts few of those cases
Let us see some compile-time error for invalid cases
Invalid Cases:
Case A: program returns value from try-block only
- Compile-time error: This method must return a result of type int
Case B: program returns value from catch-block only
- Compile-time error: This method must return a result of type int
Case C: program returns value from try-catch-finally blocks; but contains some statements after finally-block
- Compile-time error: Unreachable code
Case D: program returns value from finally-block only; but contains some statements after finally block
- Compile-time error: Unreachable code
Conclusion for Invalid cases:
- Any code present after finally-block will results compile-time error stating “Unreachable code“
- Similarly, any code after return statement will results compile-time error stating “Unreachable code“
Final Conclusion:
Out of all possible valid cases,
- If a method contains a finally-block
- then finally-block will always gets executed
- irrespective of any valid combination used in the program
In the next article, we will see detail example on return statement with finally block
References:
- https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/try.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/catch.html
- https://docs.oracle.com/javase/tutorial/essential/exceptions/
- https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html
- https://docs.oracle.com/javase/7/docs/api/java/lang/Error.html
- https://docs.oracle.com/javase/specs/jls/se7/html/jls-11.html
- https://docs.oracle.com/javase/7/docs/api/java/lang/ArithmeticException.html
- https://docs.oracle.com/javase/7/docs/api/java/lang/NullPointerException.html
- http://docs.oracle.com/javase/7/docs/api/java/lang/ArrayIndexOutOfBoundsException.html
- http://www.oracle.com/technetwork/java/effective-exceptions-092345.html
- http://otfried.org/courses/cs206/slides/slides-stackframes.pdf
Read Also:
- Exception Handling in Java
- Exception Hierarchy in Java
- Checked Exception v/s Unchecked Exception
- try-catch block in Java
- finally block in Java
- try with multiple catch block in Java
- Various methods to print exception information in Java
- return statement with finally block
- final v/s finally v/s finalize
Happy Coding !!
Happy Learning !!