未捕获的RuntimeException和finally子句:哪个先来?

try块中抛出RuntimeException而不被捕获,而finally子句调用System.exit()

 public static void main(String[] args) { try { Integer.valueOf("NotANumber"); } finally { System.out.println("finally"); System.exit(0); } } 

输出是

 finally 

如果从finally中删除System.exit(0) ,则输出为

 finally Exception in thread "main" java.lang.NumberFormatException: For input string: "NotANumber" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) at java.lang.Integer.parseInt(Integer.java:449) at java.lang.Integer.valueOf(Integer.java:554) at exception.MyExcepTest.main(MyExcepTest.java:20) 

其中“finally”可能出现在NumberFormatException的meesage之前,之后或之间。

任何人都可以解释一下吗?

在main方法退出之前肯定会执行finally块,之后由JVM打印堆栈跟踪。

也许堆栈跟踪被打印到System.err,并且两个流以不可预测的方式混合在您的控制台输出中(因为它们基本上同时生成)。

当你最后“打印”到System.err时会发生什么?

问题是,当抛出exception时…… JVM第一次执行代码,内部finally块,然后抛出exception,如果被捕获,它将抛出exception并终止线程。 所以这里当finally.clit(0)出现在finally块中时,它立即终止线程,因此JVM没有机会抛出exception。 所以输出只是“终于”

最后总是执行块。 它由语言保证。 如果尝试阻止成功终止或者抛出任何exception,则执行它。

有检查和未检查的例外。 对于未经检查的exception(运行时和错误),您不必编写catch块。 但所有exception都由打印堆栈跟踪的JVM捕获。 当您的finally块终止应用程序时,它没有机会打印堆栈跟踪,因此您没有看到它。

通常在finally块中退出程序很糟糕,因为即使您的代码成功运行它也会退出。 更常见的是,最终块通常需要清理,如关闭文件,套接字等,而不是更复杂的业务逻辑。

有两个块我们可以使用尝试那些是捕获和最后。

当抛出任何RunTimeexception(最终之前)并且最后执行block时,执行catch块,而不管是否抛出exception。

因此,如果你想在抛出exception时做一些事情,那么你可以把它放在catch(Excepion e)块中。

你看到的是JVM在终止程序执行之前执行finally块中写入的内容的责任。

当程序终止时,它默认显示抛出exception的跟踪。

最后方法总是会在try块中返回语句的情况下执行,但是在try块中抛出错误(运行时内存)的某些情况下,不能保证finally块完全执行。

在你的情况下,finally块始终执行并且主方法从JVM抛出exception,因为你没有处理exception。