Reputation: 1291
I'm not familiar with java and I've been recently looking at some code written by some colleagues that's baffling me. Here's the gist of it:
public response newStuff(//random data inside) {
try {
response or = //gives it a value
log.info(or.toString());
return or;
}
catch ( Exception e) {
e.printStackTrace();
}
finally {
return null;
}
}
Is there really any point in adding a finally block here? Couldn't I just add the return null inside the catch block, which would execute the same behavior, or am I wrong?
Upvotes: 35
Views: 10671
Reputation: 24053
I've read that a lot of people simply answer "don't use return
in a finally block", without any explanation. Well, actually the code you posted is a good example where a return
in a finally
block is causing massive confusion. Even the, as of time of writing this, most upvoted answer, got it wrong. Your code will always execute the return null;
as last command, even if there is an Exception.
But I can think of a situation where a return
in a finally
block actually makes sense. It appears to me that the goal of the author of your code was that the method never throws a Throwable
, but returns null
instead. This can actually be achieved if you modify the code like this:
public Result newStuff() {
Result res = null;
try {
res = someMethod();
log.info(res.toString());
}
catch (Exception e) {
e.printStackTrace();
}
finally {
return res;
}
}
But note that this will not call printStackTrace()
on Error
s and Throwable
s which are not Exception
s.
Upvotes: 4
Reputation: 6198
Actually, no. Finally is (nearly) always run, no matter what the result in the try-catch block; so this block always returns null
. Here, look at this example:
public class Finally {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(finallyTester(true));
System.out.println(finallyTester(false));
}
public static String finallyTester(boolean succeed) {
try {
if(succeed) {
return "a";
} else {
throw new Exception("b");
}
} catch(Exception e) {
return "b";
} finally {
return "c";
}
}
}
It will print "c" both times.
The above mentioned exception to the rule would be if the thread itself is interrupted; e.g. by System.exit()
. This is however a rare thing to happen.
Upvotes: 23
Reputation: 1170
The finally
is always executed no matter what, and normally can be used to close sessions, etc.
Don't put returns inside a finally block.
Upvotes: 5
Reputation: 726589
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;
Upvotes: 31
Reputation: 8975
First understand why we need this three blocks in simple words for beginners.
1)try block: If you have doubt that your code will lead to an exception then put in try block
2)catch block: If exception arises then a piece of code you need to perform should be written in this block
3)finally block: If you want your piece of code to be executed no matters if exception arises or not then we go for finally block. Mainly this block is use for releasing resources. For example:
try{
Connection conn=//something;
//some code for database operations
}catch(SQLException e){
e.printStackTrace()
}finally{
conn=null;
}
No matter what is result, you have to make connection as null because it is heavy object which if referenced will create load on database as only few connection objects are available. Hence best way to keep them in finally block.
In your case, return null in finally block is bad approach as it will always return null although exception arises or not.
Upvotes: 1
Reputation: 342
Finally block is used if you want to execute some statements even if code in try block or catch block generates an exception or not. But as you are using return in try block then there is no significance of putting a return in finally block. You can return directly from catch block and can remove finally block.
Upvotes: 1
Reputation: 1447
The need of finally block is where when you have such a code that should always be executed like you want to close your input stream or you want to close any connection etc.Just googled about this you will easily find the example for this.
In your case you are writing a method where you are returning something in try block and at the end you are writing finally block where you are returning null.I don't see any use of finally block here.
Upvotes: 2
Reputation: 1451
There should be no return
statement in the finally block,remove return
.
Upvotes: 3
Reputation: 1322
The "Finally" block will execute regardless of whether the "Catch" fires or not. So the behaviour is different than if you just put "return null" in the Catch block.
Upvotes: 3
Reputation: 21858
This looks like a very bad practice. In this case your code will always return null
.
The finally
block is called last after the try-catch
block runs. No matter if the try
finished or the exception
block was called. In this case, no matter which path of code is ran, you will always return null.
In the "normal" case where you put the return null
after the finally there's indeed a chance to return something (either from the try
or from the catch
block) and if no flow yields a return object, you fall back to the return null
, but you don't always return null.
Upvotes: 4