为什么允许main()方法声明异常



"处理或声明。这就是法律"-头部优先

但是,这是一条好的法律吗?让我先举一个例子:

public static void main(String[] args) throws Exception {
m1();
}
static void m1() throws Exception{
m2();
}
static void m2() throws Exception {
throw new Exception();
}

m2()抛出异常,m1()调用m2(),这意味着它必须处理声明。嗯,让我们宣布它。然后main()调用m1(),它具有相同的轮询:宣言或者句柄。我再次决定声明,代码编译得很好。

好吧,它是有效的,但是谁处理了这个异常呢?看起来没有人这么做。我知道我是个初学者,但我不喜欢那种声音。是的,有些方法可以决定是声明还是处理异常,但为什么是main()?主方法不应该是一个只处理的方法吗?以这种方式,没有任何例外可以";滑动";。

我是不是错过了什么?我真的很惊讶,main方法只声明异常是可以的,因为它是最后一个地方,我们可以从技术上捕获一些东西。

谁处理了这个异常?

Java运行时做到了。

更具体地说,UncaughtExceptionHandler做到了,正如Java语言规范(JLS(第11.3节中所规定的那样。异常的运行时处理:

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

  • 如果当前线程有一个未捕获的异常处理程序集,则执行该处理程序。

  • 否则,将为作为当前线程的父线程的ThreadGroup调用方法uncaughtException。如果ThreadGroup及其父ThreadGroup没有覆盖uncaughtException,则调用默认处理程序的uncaughtException方法。

因此,默认情况下,当main()抛出未检查或已检查的异常时,内置的默认";未捕获异常处理程序";将简单地将堆栈跟踪打印到System.err,就好像在调用main()之前执行了以下操作一样:

Thread.setDefaultUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler());
class DefaultUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
e.printStackTrace();
}
}

在";未捕获异常处理程序";调用后,线程将终止,就像您只是从main()方法返回一样,除非代码启动了仍在运行的非守护进程线程,否则程序将结束。

应用程序可能包含多个具有main方法的类。在这种情况下,应用程序应该声明一个清单来知道哪个main是入口点(第一个调用的方法(。Main方法可以从另一个方法或另一个主方法作为静态方法调用,并且可以引发任何异常。如果您至少在入口点没有捕捉到异常,那么从应用程序返回到java虚拟机的异常,然后用异常来设计要做的事情。jvm通常会向操作系统打印错误消息并返回0以外的值。

最新更新