Returning from a finally block in Java - java

I was surprised recently to find that it's possible to have a return statement in a finally block in Java.
It seems like lots of people think it's a bad thing to do as described in 'Don't return in a finally clause'. Scratching a little deeper, I also found 'Java's return doesn't always' which shows some pretty horrible examples of other types of flow control in finally blocks.
So, my question is, can anyone give me an example where a return statement (or other flow control) in a finally block produces better / more readable code?

I had a REALLY hard time to track down a bug years ago that was caused by this. The code was something like:
Object problemMethod() {
Object rtn = null;
try {
rtn = somethingThatThrewAnException();
}
finally {
doSomeCleanup();
return rtn;
}
}
What happened is that the exception was thrown down in some other code. It was being caught and logged and rethrown within the somethingThatThrewAnException() method. But the exception wasn't being propagated up past problemMethod(). After a LONG time of looking at this we finally tracked it down to the return method. The return method in the finally block was basically stopping the exception that happened in the try block from propagating up even though it wasn't caught.
Like others have said, while it is legal to return from a finally block according to the Java spec, it is a BAD thing and shouldn't be done.

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....

javac will warn of return in finally if you use the -Xlint:finally. Originally javac emitted no warnings - if something is wrong with the code, it should fail to compile. Unfortunately backwards compatibility means that unanticipated ingenious foolishness cannot be prohibited.
Exceptions can be thrown from finally blocks, but in that case the exhibited behaviour is almost certainly what you want.

Adding control structures and returns to finally{} blocks are just another example of "just because you can" abuses which are scattered throughout virtually all development languages. Jason was right in suggesting it could easily become a maintenance nightmare - the arguments against early returns from functions apply more-so to this case of "late returns".
Finally blocks exist for one purpose, to allow you to completely tidy up after yourself, no matter what happened in all the preceeding code. Principally this is closing / releasing file pointers, database connections etc., though I could see it being stretched to say adding in bespoke auditing.
Anything that affects the return of the function should lie in the try{} block. Even if you had a method whereby you checked an external state, did a time consuming operation, then checked that state again in case it became invalid, you would still want the second check inside the try{} - if it sat inside finally{} and the long operation failed, you would then be checking that state a second time needlessly.

A simple Groovy Test:
public class Instance {
List<String> runningThreads = new ArrayList<String>()
void test(boolean returnInFinally) {
println "\ntest(returnInFinally: $returnInFinally)"
println "--------------------------------------------------------------------------"
println "before execute"
String result = execute(returnInFinally, false)
println "after execute -> result: " + result
println "--------------------------------------------------------------------------"
println "before execute"
try {
result = execute(returnInFinally, true)
println "after execute -> result: " + result
} catch (Exception ex) {
println "execute threw exception: " + ex.getMessage()
}
println "--------------------------------------------------------------------------\n"
}
String execute(boolean returnInFinally, boolean throwError) {
String thread = Thread.currentThread().getName()
println "...execute(returnInFinally: $returnInFinally, throwError: $throwError) - thread: $thread"
runningThreads.add(thread)
try {
if (throwError) {
println "...error in execute, throw exception"
throw new Exception("as you liked :-)")
}
println "...return 'OK' from execute"
return "OK"
} finally {
println "...pass finally block"
if (returnInFinally) return "return value from FINALLY ^^"
// runningThreads.remove(thread)
}
}
}
Instance instance = new Instance()
instance.test(false)
instance.test(true)
Output:
test(returnInFinally: false)
-----------------------------------------------------------------------------
before execute
...execute(returnInFinally: false, throwError: false) - thread: Thread-116
...return 'OK' from execute
...pass finally block
after execute -> result: OK
-----------------------------------------------------------------------------
before execute
...execute(returnInFinally: false, throwError: true) - thread: Thread-116
...error in execute, throw exception
...pass finally block
execute threw exception: as you liked :-)
-----------------------------------------------------------------------------
test(returnInFinally: true)
-----------------------------------------------------------------------------
before execute
...execute(returnInFinally: true, throwError: false) - thread: Thread-116
...return 'OK' from execute
...pass finally block
after execute -> result: return value from FINALLY ^^
-----------------------------------------------------------------------------
before execute
...execute(returnInFinally: true, throwError: true) - thread: Thread-116
...error in execute, throw exception
...pass finally block
after execute -> result: return value from FINALLY ^^
-----------------------------------------------------------------------------
Question:
One interesting point for me was to see how Groovy deals with implicit returns. In Groovy it is possible to "return" from a method simply leaving a value at the end (without return). What do you think happens, if you uncomment the runningThreads.remove(..) line in the finally statement - will this overwrite the regular return value ("OK") and cover the exception?!

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.

Related

ScheduledThreadPoolExecutor produces unreachable code

In my eclipse plugin I use a ScheduledExecutorService for a repeating task. However this seems to lead to some unreachable code within the scheduled task because I can set a breakpoint in eclipse up to a certain line and it will be reached in the debugger but when I set it one line further it is not reached... Just nothing happens then, no exception just nothing.
When I try to overstep this respective line I land somewhere in the sources of the ScheduledThreadPoolExecutor and my stack shows this:
ScheduledThreadPoolExecutor$ScheduledFutureTask<V>(FutureTask<V>).run() line: not available [local variables unavailable]
Whats going on here?
Okay the problem was that there was actually an exception being thrown but it seems like the ScheduledExecutorService swallows it without telling anything about it...
I foud this out by surrounding my code in the run-method with a generic try-catch-block like this:
#Override
public void run() {
try {
// Code
} catch (Exception e) {
e.printStackTrace();
}
}

What is the cost of try catch blocks?

How much better is:
if (condition) {
try {
//something
} catch(SomeEx ex) {}
}
instead of this:
try {
if (condition) {
//something
}
} catch(SomeEx ex) {}
What actually JVM do when I enter try block ?
EDIT:
I don't want to know that in second example always go in to try... Please answer the question.
Execution wise at run time, as long as there is no exception, try does not cost you anything. It only costs run time as soon as an exception occurs. And in that situation it is much slower that an if evaluation.
In the JVM spec, you see that there is no extra byte code generated on the execution path:
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.12
try {if (condition) {...}} catch(SomeEx ex) {}
Here you handled the exception if it is arised condition of if also if arised inside if-block.
if (condition) {try {...} catch(SomeEx ex) {}}
Here you handle exception if is arised only inside the if-block. If something goes wrong in if condition then it will not be handled.
So it is depends upon the actual senario.
From the perfomance point of view it should be the same. Throwing of the exception is a costly operation (for starters, the stacktrace must be created and populated). The mere existence of the try block has no (or negligible) performance penalty.
See Should java try blocks be scoped as tightly as possible.
What actually JVM do when I enter try block ?
From JLS 14.20.1. Execution of try-catch:
A try statement without a finally block is executed by first executing the try block. Then there is a choice:
If execution of the try block completes normally, then no further action is taken and the try statement completes normally.
If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
If the run-time type of V is assignment compatible with (§5.2) a catchable exception class of any catch clause of the try statement, then the first (leftmost) such catch clause is selected. The value V is assigned to the parameter of the selected catch clause, and the Block of that catch clause is executed, and then there is a choice:
If that block completes normally, then the try statement completes normally.
If that block completes abruptly for any reason, then the try statement completes abruptly for the same reason.
If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the try statement completes abruptly because of a throw of the value V.
If execution of the try block completes abruptly for any other reason, then the try statement completes abruptly for the same reason.
EDIT:
For a complete Exception description see the JVM 2.10 link in The New Idiot's answer.
If you see oracle docs
>try {
code
}
catch and finally blocks . . .
The segment in the example labeled code contains one or more legal lines of code that could throw an exception.
So,If you feel doubt on your If condition that it will throw an exception put it inside.Otherwise put outside.
if (condition) {
try {
//something
} catch(SomeEx ex) {}
}
is better to use since it executes the try block if the condition is ok.JVM compiles the try block and validated the catch block or a finally block. I think advantage is not in the compile time but in the run time. Compile time I think no advantage at all
Exceptions should be exceptional case , not every time the code runs. So better to check for the condition before trying !
if (condition) {
try {
//something
} catch(SomeEx ex) {}
}
Make sure , if (condition) itself doesn't throws an Exception.
It depends on your usage and functionality . For example this would be better :
if (someObject!=null) {
try {
someObject.getSomething(); // getSomething() potentially throws some Exception
} catch(SomeEx ex) {}
}
What actually JVM do when I enter try block ?
Read JVM spec 2.10.

Java try- catch- finally block

If I run the following code:
try{
return false;
} catch(Exception e){
e.printStackTrace();
}
finally{
return true;
}
why does it return true?
From the Java Language Specification section 14.20.2
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).
(my italics). A return is one kind of "abrupt completion", in other words the return from the finally overrules the one from inside the try.
It returns true because whenever a finally block completes abruptly, either by return-ing or by throwing an exception, that completion supersedes any previous return-value or exception. (See §14.20.2 "Execution of try-finally and try-catch-finally" in the Java Language Specification, Java SE 7 Edition.)
Because no matter what happens in the try catch portion, the finally block will always do what you ask so in this case it returns true. Just remove the finally statement and it should return false.
Finally block doesnot execute when try or catch block terminate by calling System.exit function. Similarly if the thread executing try catch dies while executing try or catch block then finally block may not execute.
So its likely that your try catch finally block will almost always return true even if your try block is returning false .
Because the finally block will always be executed if a return is encountered.

; at end of condition causing unexpected behaviour

Just found a bug in this code :
for(String link : tempList1){
if(!tempList2.contains(link));{
listToPopulate.add(link);
}
}
The ';' at the end of if(!tempList2.contains(link)) causes the condition to evaluate to true, even though it should be false. Why is this occurring ?
Fix is to just remove the ';'
The compiler sees an if condition followed by a stand-alone block. With standard indenting, it would look like this:
for(String link : tempList1){
if(!tempList2.contains(link))
; // ; is a no-op statement.
{
listToPopulate.add(link);
}
}
http://en.wikipedia.org/wiki/NOP#NOP_code
The simplest possible statement in C that behaves like a NOP is the so called null statement, which is just a semi-colon in a context requiring a statement.
Java inherited this syntax from C.
The ; in line 2 ends the block following the if. The next { opens a new block that has no condition around it.
if(expr);
{
dosomething();
}
is the same as
if(expr)
{
}
{
dosomething();
}
e.g. the block containing dosomething is not part of the if statement since the ; terminates the if statement.
The if statement is not evaluating to true, it's just not relevant.
As others said,
if([condition]);
somecode;
is similar to
if([condition])
{}
somecode
If you are using Eclipse, you can enable the "empty statement" warning. This will let you see easily when such an empty statement is written, as this is generally unintended and can be annoying to debug. It is in Eclipse preferences (Java > Compiler > Errors/Warnings).
Because the ; is causing the end of the if condition, causing the if statement itself to have no effect.
The above is equivalent to:
for(String link : tempList1){
if(!tempList2.contains(link)) {
// do nothing
}
// the below is just an empty block, it will be executed always.
{
listToPopulate.add(link);
}
}
The evaluation of the condition does not change. What does change, however, is that the following line is no longer inside the loop and is executed unconditionally:
listToPopulate.add(link);
In other words, the code becomes equivalent to:
for(String link : tempList1){
if(!tempList2.contains(link)) {
}
listToPopulate.add(link);
}
Semicolon designates the end of the statement and {} indicate a new block of code. So the condition is evaluated and ignored as there is a semicolon. and listToPopulate.add(link); is always executed as it is not tied to earlier if statement.

Java Try Catch Finally blocks without Catch

I'm reviewing some new code. The program has a try and a finally block only. Since the catch block is excluded, how does the try block work if it encounters an exception or anything throwable? Does it just go directly to the finally block?
If any of the code in the try block can throw a checked exception, it has to appear in the throws clause of the method signature. If an unchecked exception is thrown, it's bubbled out of the method.
The finally block is always executed, whether an exception is thrown or not.
A small note on try/finally: The finally will always execute unless
System.exit() is called.
The JVM crashes.
The try{} block never ends (e.g. endless loop).
The Java Language Specification(1) describes how try-catch-finally is executed.
Having no catch is equivalent to not having a catch able to catch the given Throwable.
If execution of the try block completes abruptly because of a throw of a value V, then there is a choice:
If the run-time type of V is assignable to the parameter of any catch clause of the try statement, then …
…
If the run-time type of V is not assignable to the parameter of any catch clause of the try statement, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).
(1) Execution of try-catch-finally
The inner finally is executed prior to throwing the exception to the outer block.
public class TryCatchFinally {
public static void main(String[] args) throws Exception {
try{
System.out.println('A');
try{
System.out.println('B');
throw new Exception("threw exception in B");
}
finally
{
System.out.println('X');
}
//any code here in the first try block
//is unreachable if an exception occurs in the second try block
}
catch(Exception e)
{
System.out.println('Y');
}
finally
{
System.out.println('Z');
}
}
}
Results in
A
B
X
Y
Z
The finally block is always run after the try block ends, whether try ends normally or abnormally due to an exception, er, throwable.
If an exception is thrown by any of the code within the try block, then the current method simply re-throws (or continues to throw) the same exception (after running the finally block).
If the finally block throws an exception / error / throwable, and there is already a pending throwable, it gets ugly. Quite frankly, I forget exactly what happens (so much for my certification years ago). I think both throwables get linked together, but there is some special voodoo you have to do (i.e. - a method call I would have to look up) to get the original problem before the "finally" barfed, er, threw up.
Incidentally, try/finally is a pretty common thing to do for resource management, since java has no destructors.
E.g. -
r = new LeakyThing();
try { useResource( r); }
finally { r.release(); } // close, destroy, etc
"Finally", one more tip: if you do bother to put in a catch, either catch specific (expected) throwable subclasses, or just catch "Throwable", not "Exception", for a general catch-all error trap. Too many problems, such as reflection goofs, throw "Errors", rather than "Exceptions", and those will slip right by any "catch all" coded as:
catch ( Exception e) ... // doesn't really catch *all*, eh?
do this instead:
catch ( Throwable t) ...
Java versions before version 7 allow for these three combinations of try-catch-finally...
try - catch
try - catch - finally
try - finally
finally block will be always executed no matter of what's going on in the try or/and catch block. so if there is no catch block, the exception won't be handled here.
However, you will still need an exception handler somewhere in your code - unless you want your application to crash completely of course. It depends on the architecture of your application exactly where that handler is.
Java try block must be followed by either catch or finally block.
For each try block there can be zero or more catch blocks, but only one finally block.
The finally block will not be executed if program exits(either by calling System.exit() or by causing a fatal error that causes the process to abort).
how does the try block work if it
encounters an exception or anything
throwable
The exception is thrown out of the block, just as in any other case where it's not caught.
The finally block is executed regardless of how the try block is exited -- regardless whether there are any catches at all, regardless of whether there is a matching catch.
The catch blocks and the finally are orthogonal parts of the try block. You can have either or both. With Java 7, you'll be able to have neither!
Don't you try it with that program? It'll goto finally block and executing the finally block, but, the exception won't be handled. But, that exception can be overruled in the finally block!
The finally block is executed after the try block completes. If something is thrown inside the try block when it leaves the finally block is executed.
Inside try block we write codes that can throw an exception.
The catch block is where we handle the exception.
The finally block is always executed no matter whether exception occurs or not.
Now if we have try-finally block instead of try-catch-finally block then the exception will not be handled and after the try block instead of control going to catch block it will go to finally block.
We can use try-finally block when we want to do nothing with the exception.
Regardless of exception thrown or not in try block - finally block will be executed. Exception would not be caught.

Categories

Resources