未捕获Java异常

C. *_*oss 42 java exception try-catch

为什么Java中的一些例外没有被捕获catch (Exception ex)?这是代码完全失败,出现未处理的异常.(Java版本1.4).

public static void main(String[] args) {
    try {
        //Code ...
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}
Run Code Online (Sandbox Code Playgroud)

我得到了 Exception in thread "main" java.lang.NoSuchMethodError

但这很有效

public static void main(String[] args) {
    int exitCode = app.SUCCESS_EXIT_CODE;
    try {
        //Code ...
    } catch (java.lang.NoSuchMethodError mex){
        System.err.println("Caught NoSuchMethodError");
        mex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}
Run Code Online (Sandbox Code Playgroud)

我明白了 Caught NoSuchMethodError java.lang.NoSuchMethodError:

我认为捕获异常会捕获所有异常?我怎样才能捕获java中的所有异常?

Jon*_*eet 120

因为一些例外不是来自Exception- 例如ThrowableError.

基本上,类型层次结构是:

       Object
         |
      Throwable
     /         \
Exception      Error
Run Code Online (Sandbox Code Playgroud)

只有Throwables和派生类可以被抛出,所以如果你抓住了Throwable,那真的会抓住一切.

Throwable,Exception以及任何异常,从获得Exception 其他比那些源自RuntimeException数作为检查的异常 -它们是你必须声明你会扔,或者如果你调用的东西,抛出他们抓住的人.

总而言之,Java异常层次结构有点混乱......

  • @R.Bemrose - 它们符合Java语言规范:"每个异常都由Throwable类或其子类之一的实例表示"和"未经检查的异常类是RuntimeException类及其子类,以及类Error及其子类". (2认同)

Pow*_*ord 6

Errors不是Exception.

类Exception及其子类是Throwable的一种形式,它表示合理的应用程序可能想要捕获的条件.

- JavaDoc for java.lang.Exception

Error是Throwable的子类,表示合理的应用程序不应该尝试捕获的严重问题.

- java.lang.Error的JavaDoc

您可能想要捕获某些错误,例如ThreadDeath.ThreadDeath被归类为错误,如下所述

ThreadDeath类特别是Error而不是Exception的子类,即使它是"正常发生",因为许多应用程序捕获所有出现的Exception,然后丢弃该异常.

- 用于ThreadDeath的JavaDoc

但是,由于现在不推荐使用Thread的stop()方法,因此不应该使用它,因此您永远不应该看到ThreadDeath.