当我浏览JLS 8 11.2时,我遇到了以下规则:
Java编程语言要求程序包含 检查异常的处理程序,可能由执行a导致 方法或构造函数(§8.4.6,§8.8.5)。这个编译时检查 异常处理程序的存在旨在减少数量 未正确处理的例外情况。对于每个检查的异常 这是一个可能的结果,方法的throws子句或 构造函数必须提到该异常的类或其中之一 该异常类的超类(第11.2.3节)。
我无法明白这一规则。例如,我理解这两个程序
class Main
{
public static void main (String[] args) throws Exception
{
throw new Exception();
}
}
和
class Main
{
public static void main (String[] args) throws Exception
{
try{
throw new Exception();
} catch (Expection e){ }
}
}
结构良好。
但规则要求程序包含任何已检查异常的处理程序,而第一个程序则不然。实际上,看一下处理程序的定义:
每个异常都由Throwable类的实例表示 或其子类之一(第11.1节)。这样的物体可以用来携带 从处理程序发生异常的点开始的信息 抓住它。 处理程序由try的catch子句建立 陈述(§14.20)。
强调我的。
所以,在第一个程序中没有任何处理程序,但
Java编程语言要求程序包含 检查异常的处理程序
你能否澄清这条规则?
答案 0 :(得分:1)
How does the JVM handle an exception thrown by the main method详细介绍了这一点。
本质上,这是由JVM的内部完成的 - 因此免除了任何JLS规则。如果您愿意,可以覆盖此行为。
public static void main(String[] args) throws Exception {
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("I caught it !" + e);
}
});
throw new Exception();
}
我找不到除JLS execution chapter以外的任何正式规范,只涵盖main()的定义。它可能不存在,并不是所有的世界都有很好的记录。 java运行程序的The c code使用JNI。这应该可以让您了解正在发生的事情以及JLS与此无关的原因。
/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
ReportExceptionDescription(env);
goto leave;
}
/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);
/*
* The launcher's exit code (in the absence of calls to
* System.exit) will be non-zero if main threw an exception.
*/
ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1;