try/finally without catch and return value
我有一个计划如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
运行上述程序后,在控制台中看到以下结果:
1 2 3 4 | finally Exception in thread"main" java.lang.ArithmeticException: / by zero at Main.test(Main.java:17) at Main.main(Main.java:7) |
号
此行为正常,因为向主方法引发异常。
然后我将代码更改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
当运行上述程序时,我在控制台中看到以下结果:
1 2 | finally after call , res = 20 |
。
我的问题与第二种格式有关。为什么当返回finally块时,异常不被抛出到main方法?
当抛出异常时,它将首先通过您的
如果您的
另一方面,如果您的
- 参考:JLS关于Try Finally
最后看看try catch的执行情况。
从Java语言规范JLS-1420.2
If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is discarded and forgotten).
号
来自JLS(Emphasis Mine):
If execution of the try block completes abruptly because of a throw of
a value V, then there is a choice:
[...]
If the run-time type of V is not assignment compatible with a catchable exception class of any catch clause of the try statement, then the finally
block is executed. Then there is a choice:
If the finally block completes normally, then the try statement completes abruptly because of a throw of the value V.
If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S (and the throw of value V is
discarded and forgotten).
号
这意味着,如果在
除
在
第一种情况:
1 2 3 4 5 6 | try { throw new Exception(); } finally { //Exception will be lost, normal shutdown of the method return; } |
第二种情况:
1 2 3 4 5 | try { throw new Exception(); } finally { //Exception won't be lost, we'll get Exception in the main method } |
号
第三种情况:
1 2 3 4 5 6 | try { throw new Exception(); } finally { throw new IOException(); // we lost Exception, IOException will be thrown } |
注意:使用
finally块中的所有内容都是在引发异常之前执行的,因此如果返回finally块,则不会引发异常。出于这个原因,从finally块返回通常是一个坏主意。
看看这个博客,了解一些关于这个的信息。
In first program when ArithmeticException occur in try block then call the finally block and after execute the finally block , exception occur . because exception is not handled by program .
Second Program when finally block execute after that return statement execute and no exception occur because after the return statement execute compiler return in main method and remaining execution will not execute in finally block . So exception will not occur .
号
因为finally块总是被执行的,不管是否发生异常,如果您从finally方法返回,那么您将把您的执行发送到调用方法,并且您将丢失异常。所以它也会产生警告。
。
在第一种情况下,finally块作为其行为执行,但它没有捕获异常,而是通过main方法抛出异常。通过这个例子检查它
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public class HelloWorld{ public static void main(String []args)throws Exception { try { int res = test(); System.out.println("after call , res =" + res) ; } catch(Exception ex) { System.out.println("Main Catch") ; } } public static int test()throws Exception { try { return 10/0; } finally { System.out.println("finally") ; } } } |
。
在上述代码中,执行了
在第二种情况下,您返回了数字,因此主方法中没有异常。
如果你读JavaDOC,那么它会说,
它允许程序员避免清理代码被返回、继续或中断意外绕过。将清理代码放在finally块中始终是一个好的实践,即使在没有预料到异常的情况下也是如此。
因此,如果在finally块之后放置清理代码,那么如果有异常,就不会调用它。
The return statementin the finally block was basically stopping the
exception that happened in the try block from propagating up even
though it wasn't caught.
号
但是Java编译器在编写这段代码时确实会发出警告。虽然
这似乎是
看看这里
Java的EDCOX1 0不总是返回,这可能会娱乐。