【问题标题】:Why is main() method allowed to declare exceptions?为什么 main() 方法允许声明异常?
【发布时间】:2021-02-02 13:34:16
【问题描述】:

“处理或申报。这是法律。” - 头脑优先

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

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() 并且它具有相同的轮询:declarehandle。我再次决定声明它并且代码编译得很好。

好的,它有效,但是谁处理了这个异常?好像没有人做过。我知道我是初学者,但我不喜欢那样的声音。是的,有些方法可以决定是声明还是处理异常,但为什么main()? main 方法不应该是一种只处理的方法吗?这样一来,任何一个例外都不会“溜走”。

我错过了什么吗?老实说,我很惊讶 main 方法只声明异常是可以的,因为知道这是 最后一个地方我们可以在技术上捕获一些东西。

【问题讨论】:

  • 异常是为程序状态未知的意外情况设计的。如果你知道它,你可以处理异常。否则,程序崩溃比继续处理错误数据要好。
  • 它转到线程的默认异常处理程序,该处理程序无论如何都存在,因为也可能发生未经检查的异常。在main 本身中处理异常被认为是最好的,但您可以将其留给默认的异常处理程序。
  • @NomadMaker,我不同意异常意味着“程序的状态未知”。例外只是意味着“我无法完成要求我做的事情”......一般来说,取例程的名称并在其开头添加“我无法......”......对于示例“ProcessFile”如果无法处理文件,则应引发异常。如果提供了错误的密码,“ValidateLogin”应该not 抛出异常......在这种情况下它能够验证用户,即登录失败。但是,如果用户数据库不可用,那么should会抛出异常。
  • @JoelFan 如果异常处理接近源,你可能是对的。但是,如果一个异常一直到 main(),那么很有可能无法重建发生的事情。然而,如果一个方法不能完成所要求的事情,那么它应该返回一个错误值而不是抛出一个异常。
  • 没有人处理它 -> 程序崩溃。抓得越快,停止的代码就越少

标签: java exception throws


【解决方案1】:

谁处理了这个异常?

Java 运行时做到了。

更具体地说,UncaughtExceptionHandler 确实如此,如 Java 语言规范 (JLS) 部分 11.3. Run-Time Handling of an Exception 中所述:

如果找不到可以处理异常的catch子句,则终止当前线程(遇到异常的线程)。终止前,所有finally子句都被执行,未捕获的异常按如下规则处理:

  • 如果当前线程设置了未捕获的异常处理程序,则执行该处理程序。

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

因此,默认情况下,当main() 抛出异常时,无论是未检查还是检查,内置的默认“未捕获异常处理程序”将简单地将堆栈跟踪打印到System.err,就好像在@ 之前执行了以下操作987654334@ 被调用:

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

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

【讨论】:

  • 从技术上讲,堆栈跟踪转到 System.err,而不是 System.out。
  • @VGR 当我输入它时,我实际上在想,但我的手指仍然输入out。该死的肌肉记忆,或任何它的名字。习惯?
【解决方案2】:

应用程序可能包含多个具有 main 方法的类。在这种情况下,应用程序应该声明一个清单以了解哪个 main 是入口点(第一个调用方法)。主方法可以从另一个方法或另一个主方法作为静态方法调用,并且可以抛出任何异常。如果您至少在入口点没有捕获异常,那么异常从您的应用程序返回到 java 虚拟机,然后 mashine 决定如何处理异常。通常jvm会向操作系统打印错误信息并返回0以外的值。

【讨论】:

    猜你喜欢
    • 2018-07-29
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    • 2018-08-15
    • 2012-03-07
    • 2017-09-04
    • 1970-01-01
    相关资源
    最近更新 更多