在main方法中,实际上是谁处理抛出的异常?

5
如果我们在main方法中抛出异常,但未处理它,程序将正常工作。实际上,这并不是一个好的编程习惯。
public static void main(String[] args) throws IOException {
    throw new IOException(); //OK
}

但是Java要求程序中必须处理任何已检查的异常,因此应该处理IOException。在这种情况下,谁实际上处理IOException?

请注意,Java语言规范定义,如果将异常封装在包含类型为Exception超类的catch子句的try块中,则异常将被处理。


1
@KorayTugay 什么?你的评论似乎完全没有建设性。 - user3663882
2
给我点踩的人,能否解释一下原因?我询问了JVM工作原理的正式解释。 - user3663882
我很惊讶这个问题只在一年前被问到,之前没人问过。这绝对是一个值得提出的好问题。+1 - user3437460
3个回答

9
如果你没有采取任何特殊措施来捕获异常,那么将会执行线程组默认的uncaughtException。这在JLS第11.3章中有说明。
当找不到能够处理异常的catch子句时,当前线程(遇到异常的线程)将被终止。终止前,所有finally子句将被执行,并根据以下规则处理未捕获的异常:
1. 如果当前线程设置了未捕获异常处理程序,则执行该处理程序。 2. 否则,为当前线程的父线程组调用方法uncaughtException。如果ThreadGroup及其父级ThreadGroups不覆盖uncaughtException,则调用默认处理程序的uncaughtException方法。
此外,ThreadGroup.uncaughtException 的 javadoc 读作下文所示:
当线程组中的线程因未捕获的异常而停止,并且该线程没有特定的Thread.UncaughtExceptionHandler安装时,Java虚拟机会调用此线程组的uncaughtException方法。ThreadGroup的uncaughtException方法执行以下操作:
  • 如果此线程组具有父线程组,则使用相同的两个参数调用该父级的uncaughtException方法。
  • 否则,此方法检查是否安装了默认的未捕获异常处理程序,如果是,则使用相同的两个参数调用其uncaughtException方法。
  • 否则,此方法确定Throwable参数是否是ThreadDeath实例。 如果是,则不执行任何特殊操作。 否则,将打印一个消息,其中包含线程的名称(从线程的getName方法返回)和堆栈回溯(使用Throwable的printStackTrace方法),以标准错误流的形式。

所以,如果异常没有被catch子句捕获,它仍然会被JVM调用该方法来处理。这就解释了一切。 - user3663882
1
如果异常没有被catch子句捕获,JVM将允许抛出异常的线程的ThreadGroup(即运行“main”的线程)处理该异常。 - aioobe
这是整个地球互联网上唯一可以找到的深入解释。 - user3437460

2
如果异常未被捕获,线程或线程组的未捕获异常处理程序将被调用,然后线程终止。
JLS 第11章 指出:
如果找不到可以处理异常的 catch 子句,则当前线程(遇到异常的线程)将被终止。在终止之前,所有 finally 子句都会被执行,并且根据以下规则处理未捕获的异常:
- 如果当前线程设置了未捕获的异常处理程序,则执行该处理程序。 - 否则,为当前线程的父线程组调用方法 uncaughtException。如果 ThreadGroup 及其父 ThreadGroup 未覆盖 uncaughtException,则调用默认处理程序的 uncaughtException 方法。

1
JVM本身处理从main()抛出的异常。

你为什么这样认为?这是否在Java规范或Java虚拟机规范中提到了? - user3663882
我不记得在哪里提到过了,但这是一种常识。 - AlexR
好的,我正在寻找一个关于这个事实的正式解释。只是为了确保,这个章节没有提到它。 - user3663882
2
祝你好运。在我看来,人生太短暂了,不值得花时间去寻找已知(或显而易见)事实的正式描述。 - AlexR
2
@user3663882,那个章节确实提到了会发生什么。请记住,main函数也是由一个线程执行的(尽管是由虚拟机生成的线程)。 - aioobe
3
如果你认为这个问题不够有趣而不想费心给出一个好的答案,那么为什么还要发帖呢? - aioobe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接