谁实际处理主方法中抛出的异常?

时间:2015-02-22 08:34:49

标签: java exception

如果我们在方法main中抛出异常并且不处理它,它将正常工作。实际上

public static void main(String[] args) throws IOException {
    throw new IOException(); //OK
}

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

请注意,Java语言规范定义如果它包含一个包含catch子句的try块,则处理Exception,该类型是Exception的超类型。

3 个答案:

答案 0 :(得分:9)

如果您没有采取任何特殊措施来自行捕获异常,则会执行ThreadGroup的默认uncaughtException

这是在JLS Chapter 11.3中指定的。

  

如果找不到可以处理异常的catch子句,则终止当前线程(遇到异常的线程)。在终止之前,将执行所有finally子句,并根据以下规则处理未捕获的异常:

     
      
  1. 如果当前线程设置了未捕获的异常处理程序,则执行该处理程序。

  2.   
  3. 否则,将为作为当前线程的父级的uncaughtException调用方法ThreadGroup。如果ThreadGroup及其父ThreadGroups未覆盖uncaughtException,则会调用默认处理程序的uncaughtException方法。

  4.   

此外,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()抛出的异常。