"处理或声明。这就是法律"-头部优先
但是,这是一条好的法律吗?让我先举一个例子:
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以外的值。