当涉及从finally块返回的值时,在try块中有return语句是好的做法

时间:2010-09-04 16:06:33

标签: java

我想知道,return来自try阻止这是不错的做法?

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();
    }
  }
}

我首先想到会打印false。但是,这是输出:

open file stream
true

如您所见,如果我在return块内有try语句,我将在finally清理期间错过失败状态。

我的代码是:

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

只要关注finally块的返回值,我是否应该避免从尝试返回?

6 个答案:

答案 0 :(得分:18)

您建议的代码(问题末尾)没问题。您可以finally块返回,但您不应该 - 例如eclipse显示警告“finally块无法正常完成”。

事实上,try/finallyreturn没有直接关系。这似乎是这样,因为它是方法中唯一的构造,但是之后你可以有其他代码(例如 - 事件通知),然后返回。

至于您的问题 - 如果已经返回,则无法更改finally块中返回的变量的值。所以不要从try返回。

答案 1 :(得分:3)

return语句指示返回的值,return语句执行时truefinally确实会更改变量everything_is_fine的值,但这不会更改已执行的return语句返回的内容。

可以finally中添加另一个回复,该回复将覆盖return内的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;
    }
  }

但是,使用finally来修改控制流程并不是一种好的做法。但 肯定是可能的。在您的情况下,更好的方法是:

static boolean fun() {
    boolean everything_is_fine = true;

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

    return everything_is_fine;
  }

顺便说一句,根据现行Java naming conventions,变量名称应更改为everythingIsFine; - )

答案 2 :(得分:2)

回答为什么返回“true”:

如果从try返回变量,虽然在finally块中更改了返回的变量值,但将返回先前设置的值(在这种情况下,在try块中设置的值)。 (当然最后没有退货声明)

回答您希望实现的目标:

如果您希望更改finally块中返回的值,请按照第二种方法进行操作。即:

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

答案 3 :(得分:2)

虽然这被认为是不好的做法,但可以返回finally。这样做也胜过您在returntry区块中可能拥有的任何其他catch。证明:

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());
    }
}

将打印“从最后返回”。请在ideone上查看。

始终执行finally块(禁止拨打System.exit()或拔出电源插头)

编辑:请注意,在您的第一个代码示例中,finally块中没有返回任何内容,但如果您有return false,则您的方法将始终返回false。

答案 4 :(得分:1)

finally块中对everything_is_fine的赋值不会影响返回的内容。对我来说,这看起来很糟糕。意图是什么?

答案 5 :(得分:0)

如果你需要返回一个依赖于在finally块中运行的代码的东西,那么你需要将你的返回放在try块之外;正如其他人所说的,只有一份退货声明是好的做法。

话虽如此,我从来没有遇到过我的返回值依赖于finally块中的计算的情况,我通常会将返回值放在try中。