问题描述
“处理或声明。这是法律。” -先行
但是,这是一部好的法律吗?让我先举一个例子:
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()
,这意味着它必须 handle 或 declare 它。嗯,让我们声明。然后main()
调用m1()
,它具有相同的轮询: declare 或 handle 。我再次决定声明,然后代码编译就可以了。
好的,它可以工作,但是谁处理了这个异常?好像没人做。我知道我是一个初学者,但我不喜欢这样的声音。是的,有些方法可以决定是声明还是处理异常,但是为什么main()
呢?主要方法不应该只是处理方法吗?这样,任何异常都不会“滑倒”。
我想念这个吗?老实说,我知道主要方法可以声明异常是可以的,我知道这是我们可以从技术上捕获到的最后一位。
解决方法
谁来处理此异常?
Java运行时做到了。
更具体地说,UncaughtExceptionHandler
按照Java语言规范(JLS)第11.3. Run-Time Handling of an Exception节的规定进行了操作:
如果找不到可以处理异常的
catch
子句,则终止当前线程(遇到异常的线程)。在终止之前,将按照以下规则执行所有finally
子句,并处理未捕获的异常:
如果当前线程设置了未捕获的异常处理程序,则将执行该处理程序。
否则,将为当前线程的父级
uncaughtException
调用方法ThreadGroup
。如果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方法,并且可以引发任何异常。如果您至少在入口点没有捕获到异常,那么异常将从您的应用程序返回到Java虚拟机,然后mashine拒绝处理异常。通常,jvm会向操作系统输出错误消息并返回非0的值。