【问题标题】:How does a return statement work after a finally block in java?在 java 中的 finally 块之后,return 语句如何工作?
【发布时间】:2018-03-21 09:54:58
【问题描述】:

这是《Java All-in-one Desk Reference》一书中的一个例子

public class CrazyWithZeros {
public static void main(String[] args) {
    try {
        int answer = divideTheseNumbers(5, 0);
    } catch (Exception e) {
        System.out.println("Tried twice, still didn't work!");
    }
}

public static int divideTheseNumbers(int a, int b) throws Exception {

    int c;
    try {
        c = a / b;
        System.out.println("It worked!");
    } catch (Exception e) {
        System.out.println("Didn't work the first time.");
        c = a / b;
        System.out.println("It worked the second time!");
    } finally {
        System.out.println("Better clean up my mess.");
    }
    System.out.println("It worked after all.");
    return c;

}

}

finally 子句执行后,ArithmeticException 被抛出回调用方法。在这种情况下,将永远不会执行语句 System.out.println("It worked after all.");。但是return c; 发生了什么?

不知道return语句是否还会返回除法的结果?

========

我尝试将“System.out.println("Better clean up my mess.");”替换为“System.out.println(c);”,然后编译,结果如下:

Didn't work the first time.  
0 
Tried twice, still didn't work!

我不敢相信变量c 可以计算出来。 (虽然是错误的数字)为什么会发生这种情况?

然后我也尝试将“System.out.println("Better clean up my mess.");”替换为“return c;”并删除了finally块下面的语句,它再次编译......由于finally块被执行,无论是否抛出任何异常try 块或被任何 catch 块捕获,返回 c;应该被执行。但结果如下:

第一次没用。

看起来c 无法返回...

【问题讨论】:

  • 试试 System.out.println(c); , 进行调试。
  • 计算机是可预测的机器。但实际上,它们只是功能强大的计算器。如果您在袖珍计算器上尝试相同的除法会发生什么?同一件事情。否则计算器将一文不值,你不能相信它们。因此,如果某些事情不起作用,不要只是再试一次,要尝试了解分裂失败的原因。可能你除以零......另外,捕捉“异常”而不是“AMoreSpecificException”是犯罪,不应该这样做。

标签: java


【解决方案1】:

return c 也没有被执行。它直接进入 main 方法中的 catch 块。

【讨论】:

    【解决方案2】:

    您对第二次执行容易出错的操作有何期望? :)

    它会生成一个与您在 catch 块中出现的类型相同的异常,但当时它不会被处理 - 您在 this 中没有另一个 try-catch > catch 块。

    finally 始终执行,无论是否发生异常或正常流程继续进行。在您的情况下,您来到 finally 异常块并将其抛出给调用者 (main),由其自己的 catch 块处理。

    不知道return语句是否还会返回除法的结果?

    你想返回什么?您还没有初始化变量c,并且该变量没有正确的记录。因此,Java 不允许在c 中写入“意外或不可预知”。

    【讨论】:

    • 这是我参考书中的一个人为示例,演示了如何使用 finally 子句。但是我很困惑 return 语句在 finally 块之后是否仍然可以正常工作,因为 ArithmeticException 被 main 方法中的 catch 块捕获......
    • @syurazetu,清理并不意味着恢复正常状态。 finally 块只是保证无论之前发生的事件如何都会执行。如果你遇到一个异常的finally 块,你就会出现这个异常。
    • c 是一个局部变量,我认为它是由 try 语句中的“c=a/b”初始化的。
    • @syurazetu,是的,但它会在表达式a/b 被求值并计算该表达式的结果之后被初始化。显然无法计算结果——出现异常
    • @Andrew Tobilko,现在说得通了。非常感谢!
    【解决方案3】:
    1. 如果一个方法在没有异常或错误的情况下执行,它会返回一些值。
    2. finally 块对是否执行 return 语句没有任何影响。 (当然,finally 块不应抛出任何进一步的异常)
    3. catch 块确定是否应进一步传播该异常或在方法内处理该异常。

    在给定的示例中,ArithmeticExceptiontry 块中抛出,并将由相应的 catch 块处理。由于catch 块再次抛出相同的异常,给定return 语句将永远不会执行。

    简而言之, return c; 在上述程序中永远不会被执行,变量c 将像任何其他局部变量一样被删除。

    【讨论】:

      猜你喜欢
      • 2020-06-17
      • 2013-06-04
      • 1970-01-01
      • 2013-05-05
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多