user1413969
user1413969

Reputation: 1291

return in try-catch's finally block in java. Is there any good point in this example?

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

Answers (10)

Flow
Flow

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 Errors and Throwables which are not Exceptions.

Upvotes: 4

blalasaadri
blalasaadri

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

X-Pippes
X-Pippes

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

Sergey Kalinichenko
Sergey Kalinichenko

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

Shoaib Chikate
Shoaib Chikate

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

Prateek
Prateek

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

kailash gaur
kailash gaur

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

vinay Maneti
vinay Maneti

Reputation: 1451

There should be no return statement in the finally block,remove return.

Upvotes: 3

WalkerDev
WalkerDev

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

Avi
Avi

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

Related Questions