20

I was wondering, is it good practice to return from try block?

package debug;

/**
 *
 * @author Owner
 */
public class Main {

  public static void main(String[] args) {
    System.out.println(fun());
  }

  static boolean cleanup() {
    // Fail to cleanup.
    return false;
  }

  static boolean fun() {
    boolean everything_is_fine = true;
    try {
      System.out.println("open file stream");
      return everything_is_fine;
    } finally {
      everything_is_fine = cleanup();
    }
  }
}

I first thought false will be printed. However, here is the output :

open file stream
true

As you can see, if I am having return statement within try block, I will miss the fail status during finally cleanup.

Shall I have the code as :

  static boolean fun() {
    boolean everything_is_fine = true;
    try {
      System.out.println("open file stream");      
    } finally {
      everything_is_fine = cleanup();
    }
    return everything_is_fine;
  }

As long as the returned value from finally block is concerned, shall I avoid return from try?

Cheok Yan Cheng
  • 47,586
  • 132
  • 466
  • 875

6 Answers6

18

Your suggested code (at the end of the question) is fine. You can return from the finally block, but you should not - for example eclipse shows a warning "finally block does not complete normally".

In fact, the try/finally aren't directly related to the return. It seems so here, because it is the only construct in the method, but you can have other code after that (for example - event notifications), and then return.

As for your question - you can't change the value of the returned variable in the finally block if it is already returned. So don't return from try.

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • @NullUserException I meant another thing, which in the context of the question should be perfectly visible. However, I rephrased the final sentence so that it's true even out of the context of the question. – Bozho Sep 04 '10 at 16:55
3

The return statement dictates what value is being returned, which at the time the return statement is executed is true. finally does change the value of the variable everything_is_fine, but that doesn't change what the already executed return statement returned.

You could add another return in finally which will override the return inside try:

static boolean fun() {
    boolean everything_is_fine = true;

    try {
      System.out.println("open file stream");
      return everything_is_fine;
    } finally {
      everything_is_fine = cleanup();
      return everything_is_fine;
    }
  }

However, the use of finally to modify the control flow is not considered good practice. It is certainly possible though. A better way of doing this in your case would be:

static boolean fun() {
    boolean everything_is_fine = true;

    try {
      System.out.println("open file stream");
    } finally {
      everything_is_fine = cleanup();
    }

    return everything_is_fine;
  }

Btw, the variable name should be changed to everythingIsFine per the prevailing Java naming conventions ;-)

samitgaur
  • 5,601
  • 2
  • 29
  • 33
2

Answer for why "true" is returned:

If variable is returned from try, though returned variables value is changed in finally block, previously set value (in this case value set in try block) will be returned. (off course there is no return statement in finally)

Answer for what you wish to achieve:

If you wish to change value to be returned in finally block then follow your second approach. i.e. :

 static boolean fun() {
    boolean everything_is_fine = true;
    try {
      System.out.println("open file stream");      
    } finally {
      everything_is_fine = cleanup();
    }
    return everything_is_fine;
  }
YoK
  • 14,329
  • 4
  • 49
  • 67
  • @NullUserException please try same and proove it. – YoK Sep 04 '10 at 16:27
  • also there are instances when finally is not always executed – Woot4Moo Sep 04 '10 at 16:28
  • @NullUserException example you are showing has "return" statement in finally. What I meant to tell with my answer was , if variable is returned from try, though value is changed for this variable in finally, earlier value will be returned. offcourse if something else is not returned from finally. Will update my answer. – YoK Sep 04 '10 at 16:39
  • @YoK I don't know what you mean by that. I can't think of a way of using a return value from your `try` block instead of the return value from the `finally` block. – NullUserException Sep 04 '10 at 16:49
  • @NullUserException return from finally is bad prac, I think you agree on it. First part on my answer suggests , why did user get "true" instead of "false", And second part suggests what to use. – YoK Sep 04 '10 at 17:00
  • I just made my answer clear about why true was returned and my suggestion about what to use. – YoK Sep 04 '10 at 17:18
  • 1
    @YoK If the OP had a `return false` in the `finally` block the method would return false. Of course if nothing is returned in the `finally` block, it will use the last return (`true` from the `try` block) – NullUserException Sep 04 '10 at 17:39
  • @NullUserException This is exactly what my answer is. did you read my answer ? – YoK Sep 05 '10 at 06:05
  • @YoK No, that is *not* what your answer is. – NullUserException Sep 05 '10 at 08:29
2

While it's considered bad practice, you can return on finally. Doing so also trumps any other returns you might've had in your try and catch blocks. Proof:

class Main
{
    public static String test() {
        try {
            except();
            return "return from try";
        } catch (Exception e) {
            return "return from catch";
        } finally {
            return "return from finally";
        }
    }

    public static void except() throws Exception {
        throw new Exception();
    }

    public static void main(String[] args) {
        System.out.println(test());
    }
}

Will print "return from finally". See it on ideone.

The finally block is always executed (barred a call to System.exit() or pulling the power plug)

EDIT: Note that in your first code sample, nothing is returned in the finally block but if you had a return false there, your method would always return false.

NullUserException
  • 83,810
  • 28
  • 209
  • 234
  • Though its possible to return from finally block, I don't consider it to be good practice.Reason being Purpose of finally block is to "cleanup". – YoK Sep 04 '10 at 16:50
  • @YoK I don't either, and I said so in my answer. – NullUserException Sep 04 '10 at 16:51
  • So your answer is not relevant As question talks about good practice. Also finally is not executed in more cases than you have put like : if the thread executing the try or catch code is interrupted or killed – YoK Sep 04 '10 at 16:55
  • 1
    This was meant more to be a comment than an answer, but was too long to fit in a comment. – NullUserException Sep 04 '10 at 16:58
  • So you put Comment in Answer section ? Tell me what you wish me to do ? – YoK Sep 04 '10 at 17:04
  • I know it is bad practice to return from finally block. But, your answer is not relevant to my question. See the stuff in bold. – Cheok Yan Cheng Sep 06 '10 at 00:37
2

The assignment to everything_is_fine in the finally block doesn't affect what is returned. It looks like a poor practice to me. What's the intention?

user207421
  • 305,947
  • 44
  • 307
  • 483
0

If you need to return something that has dependencies on code run in a finally block, then you need to put your return outside the try block; as someone else stated, it's good practice to have just one return statement.

Having said this, I have never come across as case where my return value was dependant on a calculation in the finally block, and I would normally put the return inside the try.

dsmith
  • 1,978
  • 10
  • 16