如果我们在方法main
中抛出异常并且不处理它,它将正常工作。实际上
public static void main(String[] args) throws IOException {
throw new IOException(); //OK
}
但是Java要求在程序中处理任何已检查的异常,因此应该处理IOException
。在这种情况下谁实际处理IOException?
请注意,Java语言规范定义如果它包含一个包含catch
子句的try块,则处理Exception,该类型是Exception的超类型。
答案 0 :(得分:9)
如果您没有采取任何特殊措施来自行捕获异常,则会执行ThreadGroup
的默认uncaughtException
。
这是在JLS Chapter 11.3中指定的。
如果找不到可以处理异常的catch子句,则终止当前线程(遇到异常的线程)。在终止之前,将执行所有finally子句,并根据以下规则处理未捕获的异常:
如果当前线程设置了未捕获的异常处理程序,则执行该处理程序。
- 醇>
否则,将为作为当前线程的父级的
uncaughtException
调用方法ThreadGroup
。如果ThreadGroup
及其父ThreadGroups
未覆盖uncaughtException
,,则会调用默认处理程序的uncaughtException
方法。
此外,ThreadGroup.uncaughtException
的javadoc内容如下:
当此线程组中的线程因未捕获的异常而停止并且该线程没有安装特定的
Thread.UncaughtExceptionHandler
时,由Java虚拟机调用。
uncaughtException
的{{1}}方法执行以下操作:
- 如果此线程组具有父线程组,则使用相同的两个参数调用该父线程的
ThreadGroup
方法。- 否则,此方法检查是否安装了默认的未捕获异常处理程序,如果是,则使用相同的两个参数调用其
uncaughtException
方法。- 否则,此方法确定
uncaughtException
参数是否为Throwable
的实例。如果是这样,没有什么特别的。否则,将使用ThreadDeath
的{{1}}方法将包含线程名称(从线程的getName
方法返回)和堆栈回溯的消息打印到标准错误流。
答案 1 :(得分:2)
如果未捕获到异常,则调用线程或线程组的未捕获异常处理程序,然后线程终止。
JLS chapter 11声明:
如果找不到可以处理异常的
catch
子句,那么 当前线程(遇到异常的线程)是 终止。在终止之前,所有finally
子句都会被执行 未捕获的异常根据以下规则处理:如果当前线程设置了未捕获的异常处理程序,则执行该处理程序。
否则,将为作为当前线程的父级的
uncaughtException
调用方法ThreadGroup
。如果ThreadGroup
及其父ThreadGroup
不会覆盖uncaughtException
,然后是默认处理程序的uncaughtException
方法 被调用。
答案 2 :(得分:1)
JVM本身处理从main()
抛出的异常。