在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方法抛出,因为你没有处理异常。