为什么没有try catch块来调用static void main()

时间:2015-02-08 07:04:15

标签: java exception

当我浏览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();
    }
}

DEMO

class Main
{
    public static void main (String[] args) throws Exception
    {
        try{
            throw new Exception();
        } catch (Expection e){ }
    }
}

DEMO

结构良好。

但规则要求程序包含任何已检查异常的处理程序,而第一个程序则不然。实际上,看一下处理程序的定义:

  

每个异常都由Throwable类的实例表示   或其子类之一(第11.1节)。这样的物体可以用来携带   从处理程序发生异常的点开始的信息   抓住它。 处理程序由try的catch子句建立   陈述(§14.20)。

强调我的。

所以,在第一个程序中没有任何处理程序,但

  

Java编程语言要求程序包含   检查异常的处理程序

你能否澄清这条规则?

1 个答案:

答案 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;