什么是第一 – 最后还是阻止?

考虑以下测试用例:

public class Main { static int a = 0; public static void main(String[] args) { try { test(); System.out.println("---"); test2(); } catch(Exception e) { System.out.println(a + ": outer catch"); a++; } } public static void test() { try { throw new Exception(); } catch (Exception e) { System.out.println(a + ": inner catch"); a++; } finally { System.out.println(a + ": finally"); a++; } } public static void test2() throws Exception { try { throw new Exception(); } finally { System.out.println(a + ": finally"); a++; } } } 

带输出:

 0: inner catch 1: finally --- 2: finally 3: outer catch 

什么是为什么在test()捕获发生之前最终在test2()发生的原因是另一种解释?

因为test2()中的try块没有catch块,所以只有finally块。 代码不会“跳回”调用者陷入catch ,然后“跳到” finally继续那里,就像你想象的那样。

关键点是:

  • try-(catch)-finally块中, finally执行该特定try块的finally
  • 你可以在另一个嵌套的try块中嵌套try块,并且每个嵌套的try块都可以有自己的finally块,这些块将在那些单独的try块中最后执行

所以是的, finallyfinally执行,但适用于附加的try块。

所以给出以下片段:

 try { try { throw null; } finally { System.out.println("Finally (inner)"); } } catch (Throwable e) { System.out.println("Catch (outer)"); } 

这打印( 如ideone.com上所示 ):

 Finally (inner) Catch (outer) 

观察:

  • (inner)Finally是最后(无论是否有任何catch成功)
  • Catch (outer)跟随Finally (inner) ,但那是因为Finally (inner)嵌套在(outer)内的另一个 try块内

同样,以下代码段:

  try { try { throw null; } catch (Throwable e) { System.out.println("Catch (inner)"); } finally { System.out.println("Finally (inner)"); throw null; } } catch (Throwable e) { System.out.println("Catch (outer)"); } 

这打印( 如ideone.com上所示 ):

 Catch (inner) Finally (inner) Catch (outer) 

参考

  • JLS 14.20.2执行try-catch-finally

相关问题

  • 在Java中,最终会回归特朗普吗?
  • 在Java中,是否保证要调用“finally”块(在main方法中)?
  • finally块总是运行吗?
  • 在下列情况下最终阻止会发生什么?

catch最终出现在同一个try-catch-finally范围之前。

test2在test2的try-catch-finally范围内没有捕获,所以它在离开范围之前完成了最终并落入了更高的catch。

因为finally块总是在退出范围之前执行。 调用test2()后的事件序列如下:

  1. test2()抛出exception
  2. 由于test2没有catch块,exception会传播到调用者。
  3. 由于test2有一个finally块,因此在从方法返回之前执行它。
  4. main方法中的catch捕获exception。

try – catch,最后用于避免程序因执行程序期间出现意外错误而终止程序的情况。

以下几点很重要……

1)块只有一次尝试……一个块的任意数量的catch语句,最后只有一个用于一个块的语句

2)最后是可选的。

3)catch也是可选的但如果缺少catch语句则最终必须出现。

4)对应于子例外的所有捕获必须出现在父exception的catch之前。

5)无论exception的发生如何,finally块中出现的语句总是以一个排除的方式执行。

即如果遇到System.out.exit()语句,则程序会立即终止,因此在这种情况下最终无法执行。

注意:即使在try块中出现一个return语句……然后也会执行finally中的代码。

因为, 最后是在try..catch块中执行的最后一个代码,无论是抛出,抛出然后处理,还是根本不抛出exception。

事实上,最终不会被调用的唯一时间是,如果JVM在执行它之前退出,或者执行try代码的线程被终止或中断。

回应评论: Java描述终于

 Note: If the JVM exits while the try or catch code is being executed, 

那么finally块可能不会执行。 同样,如果执行try或catch代码的线程被中断或终止,则即使应用程序作为一个整体继续,finally块也可能不会执行。

但是你是正确的,因为抛出了一个ThreadDeathexception,我找不到太多关于来自sun的冲突信息的详细信息。 这本身就是一个问题。

最后 (原谅双关语)@brainimus,如果你在finally中并抛出exception,那么最后的代码正在被执行,我的观点是最终代码没有被执行的条件。

如果您通过方法代码替换函数,您会得到:

 public class Main { static int a = 0; public static void main(String[] args) { try { try { throw new Exception(); } catch (Exception e) { // I catch only the *first* exception thrown System.out.println(a + ": inner catch"); a++; // let's go to the finally block } finally { System.out.println(a + ": finally"); a++; // we go on } System.out.println("---"); try { throw new Exception(); } finally { // executed because at the same level System.out.println(a + ": finally"); a++; } } catch(Exception e) { // I catch only the *second* exception thrown System.out.println(a + ": outer catch"); a++; } } 

第一个exception使catch块执行,然后执行第一个finally块。 由于第一个捕获块,它在外层看不到。 第二个exception是由外层的catch块拦截的,但是最后一个exception位于内层,最先执行。

首先执行try块。 如果try块中存在需要捕获的exception,则执行Catch。 最后,无论是否存在exception,都会运行块。 如果在try块内有return语句,那么在try块中返回之前,最后块执行,然后在try块中执行return。