未捕获的rununtimeexception和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消息的前面、后面或中间。

有人能解释一下吗?

最后一个块肯定会在main方法退出之前执行,并且JVM在此之后打印堆栈跟踪。

可能堆栈跟踪被打印到系统。错误,这两个流以不可预测的方式在你的控制台输出中混合在一起(因为它们基本上是同时产生的)。

当你将"finally"输出到System时会发生什么?也会犯错吗?

问题是,当出现异常时…JVM首先执行带有inside finally块的代码,如果被捕获,则抛出异常,或者抛出异常并终止线程。所以这里,当System.exit(0)出现在finally块中时,它会立即终止线程,这样JVM就没有机会抛出异常。所以输出就是"最后"

Finally块总是被执行。这是由语言保证的。如果try块成功终止或抛出任何异常,则执行该函数。

有已检查和未检查的异常。对于未检查的异常(运行时和错误),您不必编写catch块。但是所有异常都会被JVM捕获,并打印堆栈跟踪。当finally块终止应用程序时,它没有机会打印堆栈跟踪,所以您看不到它。

通常在finally块中退出程序是不好的,因为即使你的代码成功运行,它也会退出。更普遍的是,finally block通常用于清理,如关闭文件,套接字等,而不是用于更复杂的业务逻辑。

在try中可以使用两个block, catch和finally。

catch块在抛出任何运行时异常时执行(在finally之前),最后执行finally块,无论是否抛出异常。

所以如果你想对抛出的异常做些什么,你可以把它放在catch(exception e)块中。

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

当程序终止时,默认情况下会显示抛出的异常的跟踪信息

Finally方法总是会被执行,即使在try块中返回语句的情况下,但在某些情况下,抛出错误(运行时内存)在try块中,没有保证Finally块完全执行。

在你的情况下,finally块总是被执行,并且异常由JVM的main方法抛出,因为你没有处理异常。

相关内容

  • 没有找到相关文章

最新更新