Can we use return in finally block
Returning from inside a finally
block will cause exceptions
to be lost.
A return statement inside a finally block will cause any exception that might be thrown in the try or catch block to be discarded.
According to the Java Language Specification:
If execution of the try block completes abruptly for any other reason
R, then the finally block is executed, and then there is a choice:If the finally block completes normally, then the try statement
completes abruptly for reason R.
If the finally block completes abruptly for reason S, then the try
statement completes abruptly for reason S (and reason R is
discarded).
Note: As per JLS 14.17 - a return statement always completes abruptly.
Returning from a finally block in Java
The examples you provided are reason enough to not use flow-control from finally.
Even if there's a contrived example where it's "better," consider the developer who has to maintain your code later and who might not be aware of the subtleties. That poor developer might even be you....
Returning a value from a finally block
The code will never reach finally right?
No, If there is a finally block control will go to finally after try or/and catch
Because in any case finally will always execute. Except as Mike Kobit said System.exit
Thanks Jason C, From JLS 14.17. The return Statement
It can be seen, then, that a return statement always completes abruptly.
The preceding descriptions say "attempts to transfer control" rather than just "transfers control" because if there are any try statements (§14.20) within the method or constructor whose try blocks or catch clauses contain the return statement, then any finally clauses of those try statements will be executed, in order, innermost to outermost, before control is transferred to the invoker of the method or constructor. Abrupt completion of a finally clause can disrupt the transfer of control initiated by a return statement.
From JLS 14.20.2. Execution of try-finally and try-catch-finally
If execution of the try block completes normally, then the finally block is executed, and then there is a choice:
- If the finally block completes normally, then the try statement completes normally.
- If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S.
So In you code try returns 1, then control goes to finally which returns 3. so return value of function will be 3.
Returning from finally block
The difference from behaviour in Java is because try ... catch ... finally
is an expression in Kotlin, not a statement.
The way that a "try-expression" is evaluated, is defined as follows in the specification:
The try-expression evaluation evaluates its body; if any statement in the try body throws an exception (of type E), this exception, rather than being immediately propagated up the call stack, is checked for a matching catch block. If a catch block of this try-expression has an exception parameter of type T:>E , this catch block is evaluated immediately after the exception is thrown and the exception itself is passed inside the catch block as the corresponding parameter. [...]
If there is a finally block, it is evaluated after the evaluation of all previous try-expression blocks
The value of the try-expression is the same as the value of the last expression of the try body (if no exception was thrown) or the value of the last expression of the matching catch block (if an exception was thrown and matched). All other situations mean that an exception is going to be propagated up the call stack, and the value of the try-expression is undefined.
Note: as described, the finally block (if present) is always executed, but has no effect on the value of the try-expression.
So when throwing
is true, the try
, catch
, and finally
blocks are all executed, but the value of the try-expression is the value of the last expression in the catch block. This explains the behaviour in both the "explicit" and "implicit" cases.
In the "explicit return" case, return 2
is executed, but the method can't return there - the finally block still has to run! Then return 3
is executed, and now the method returns. Notably, the outer return
is never executed. You can delete the outer return
and start the method with try { ...
and get the same result.
In the "implicit return" case, 2
is evaluated, and no side effects happen since it is just a literal. Then the finally block runs, and 3
is evaluated, and again no side effects happen since it is just a literal. Now we have finished evaluating the whole try
-expression, and according to the spec, the value of the expression should be what we evaluated in the catch block - i.e. 2. And now we execute return 2
.
Side note: return ...
are also expressions, and they have the type of Nothing
(the subtype of every type), because they never evaluate to anything. This is why you are able to write return 1
etc as the last line in the try-expression blocks in the "explicit return" case. In that case, the try-expression actually has a type of Nothing
, and the outer return
is actually returning Nothing
. This is fine, because Nothing
is a subtype of Int
.
Is placing return statement before finally block a good practice?
Putting return
in the try
or even in the catch
es is absolutely fine: do whatever is clearest. Take care not to discard too many exceptions though, particularly java.lang.Throwable
as doing that can interfere with the workings of the JVM.
Note that if you have a return
in the finally
block, then the expression in the other return
is still evaluated but the result is discarded and the return value in the finally
block is returned back to the caller. Because of this, putting a return
value in the finally
block is discouraged.
try-catch-finally with return after it
The fact that the finally block is executed does not make the program forget you returned. If everything goes well, the code after the finally block won't be executed.
Here is an example that makes it clear:
public class Main {
public static void main(String[] args) {
System.out.println("Normal: " + testNormal());
System.out.println("Exception: " + testException());
}
public static int testNormal() {
try {
// no exception
return 0;
} catch (Exception e) {
System.out.println("[normal] Exception caught");
} finally {
System.out.println("[normal] Finally");
}
System.out.println("[normal] Rest of code");
return -1;
}
public static int testException() {
try {
throw new Exception();
} catch (Exception e) {
System.out.println("[except] Exception caught");
} finally {
System.out.println("[except] Finally");
}
System.out.println("[except] Rest of code");
return -1;
}
}
Output:
[normal] Finally
Normal: 0
[except] Exception caught
[except] Finally
[except] Rest of code
Exception: -1
return in try-catch's finally block in java. Is there any good point in this example?
Is there really any point in adding a finally block here?
The answer to this is a resounding "no": putting a return
statement in the finally
block is a very bad idea.
I just add the return null inside the catch block, which would execute the same behavior, or am I wrong?
It wouldn't match the original behavior, but that's a good thing, because it would fix it. Rather than returning null
unconditionally the way the original code does, the code with the return
inside the catch
block would return null
only on errors. In other words, the value returned in the try
branch would be returned to the caller unless there is an exception.
Moreover, if you add return null
after the catch
block, you would see the correct effect of returning null
on exception. I would go even further, and put a single return
in the method, like this:
response or = null;
try {
or = //gives it a value
log.info(or.toString());
} catch ( Exception e) {
e.printStackTrace();
}
return or;
The order of return value with try catch finally
This question is closely related, although it returns literals but not variables: Multiple returns: Which one sets the final return value?
In fun1
the return value is set via return a
in the catch-block. At that line the value of a
is copied into the return value. Changing a
later does not change the return value.
In fun2
you have an explicit return in the finally
block, so the return value in the finally block is what is returned.
Please read carefully through the answers in the question above for why you should not write code like that.
Another related question is this one: Returning from a finally block in Java
Will modifications to a function's return value in the finally block take effect?
The following things will happen when you will call this method:
- The expression,
x = x + 1;
will increase the value ofx
by1
i.e. its value will become1
. Then,throw new Exception();
will be executed and as a result, the control will enter thecatch
block. - Inside the
catch
block,x = x + 2;
will increase the value ofx
by2
i.e. its value will become3
which is the value that will be returned. - Since
finally
block is supposed to be executed irrespective of whether an exception is thrown or not, this block will be executed but it won't change the return value. Thus,finally
block is useless here. Typically,finally
block is used to release resources. Check this to learn more about it.
Related Topics
Invalidkeyexception Illegal Key Size
How to Make the Division of 2 Ints Produce a Float Instead of Another Int
Why Does Runtime.Exec(String) Work for Some But Not All Commands
How to Write a Custom JSON Deserializer for Gson
How to Read a Resource File from a Java Jar File
Resize an Array While Keeping Current Elements in Java
How to Stop a Java Thread Gracefully
Eclipse Can't Find Xml Related Classes After Switching Build Path to Jdk 10
Java.Text.Parseexception: Unparseable Date
How to Reference Javafx Fxml Files in Resource Folder
How to Play .Wav Files with Java
Instantiating Generics Type in Java
Differencebetween Thread.Start() and Thread.Run()
Java.Lang.Runtimeexception: Uncompilable Source Code - What Can Cause This