【问题标题】:Universal Catch Statement通用捕获声明
【发布时间】:2013-04-04 07:13:17
【问题描述】:

我想知道是否有办法编写一个在程序中抛出任何异常时激活的 catch 语句。谢谢!

【问题讨论】:

  • 从字面上看,这是不可能的,因为异常可能已经在它被抛出的点附近被捕获。如@assylias 回答中所述,您能做的最好的事情就是捕获所有未被捕获的异常。

标签: java exception error-handling


【解决方案1】:

要捕获某些代码块可能抛出的所有异常,您可以这样做:(这也将捕获您自己编写的异常) 来自How can I catch all the exceptions that will be thrown through reading and writing a file?

try {

    // exceptional block of code ...
    // ...
} catch (Exception e){

    // Deal with e as you please.
    //e may be any type of exception at all.
}

之所以有效是因为 Exception 是所有运行时异常的基类。因此,任何可能抛出的运行时异常都是异常。

这是因为所有运行时异常都继承自 Exception。请注意,Error 和 Exception Unchecked exceptions in Java: Inherit from Error or RuntimeException? 之间存在区别,在这种情况下您可能需要这样做:

try {

} catch(Throwable e) {

}

看到这个When should Throwable be used instead of new Exception?。一位用户备注:

错误在任何情况下都无法通过编程方式恢复,并且通常不会被捕获,除非用于记录目的(再次通过它)。异常可以通过编程方式恢复。它的子类 RuntimeException 表示编程错误,通常也不会被捕获。有关更多信息,请参阅 cmets。

【讨论】:

  • 应该注意,简单地尝试/捕获 Main 中的所有内容并不一定会对最终用户隐藏所有错误。您引用的任何库都可以有自己的异常处理,并且它们不一定会冒泡所有异常。库本身可以选择忽略异常、向最终用户显示堆栈跟踪、将内容记录到文件等。
  • 那只会捕获当前线程抛出的异常。
  • @assylias 好点,如果他正在制作子线程,他是否需要遵循这个(见第一个答案)stackoverflow.com/questions/2631791/…。还是有更好的方法?
  • @tigger 我已经添加了答案。
【解决方案2】:

您可以将类型设为Exception。这将捕获任何Exception,但它也没有为程序员提供太多关于哪里出了问题的信息。通常最好尝试更具体地了解已发生异常的类型,主要是出于语义原因。

理论

每种类型的 Java 异常都扩展了 Exception 类型。因为Exception是所有异常的超类,所以当一个异常被抛出时,不管它是什么类型,它仍然可以被隐式转换为Exception类型的对象。

编辑

正如 cmets 中提到的,还有可以抛出的类型 Error,因此最好使用 Throwable 类型真正捕获所有内容。 ThrowableException 更通用,但它仍然按照完全相同的原理工作。它是任何可以是thrown 的超类。

例如

try{
   // Some code
}
catch(Throwable e)
{
    // Do something. Edited due to comment!
}

【讨论】:

  • Errors 也是可投掷的,不过……你总能赶上Throwable
【解决方案3】:

是的,任何失败的错误都会被这个捕获:

try {
    //do things here
} catch (Exception e) {
    //handle exception here
}

但请注意,这通常是错误的做法。

【讨论】:

  • 如果你真的想在脚上开枪,你可以随时抓住Throwable :)
【解决方案4】:

在你的 main 中,把你所有的代码放进去

try {
    //Your code
} catch(Exception e) {
    //Handle exceptions 
}

这将处理您的代码调用的任何异常。

【讨论】:

    【解决方案5】:

    到目前为止,您收到的答案的问题是,如果您在 main 中包含“catch-all”,它只会捕获主线程上抛出的异常。

    捕获所有未捕获异常的更可靠的方法是为您的项目设置一个DefaultUncaughtExceptionHandler,例如,在您的 main 开始时,您可以调用:

    Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            //log the exception
        }
    });
    

    请注意,除了登录之外,其他任何操作通常都是不合理的,因为Throwable 可以是任何东西,包括不可恢复的错误。

    【讨论】:

    • 非常有趣。我完全没有意识到这种可能性。
    • 谢谢,这正是我想要的!我将使用它,以便每当发生错误时,它都会通过电子邮件将错误发​​送给我。
    • 哇...!几乎成功了!,我需要捕获 NPE,但是库实现了 ExecutionException(这似乎捕获了 NPE),所以没有工作:(,将保留所有其他情况,谢谢!
    • @AquariusPower 没有理由它不起作用 - 我的猜测是您在代码中捕获了 ExecutionException 而没有查看 e.getCause() 的原因(这将是 NPE) .所以实际上你正在捕获异常 - 但忽略它 - 并且未调用未捕获的异常处理程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-21
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 2021-10-25
    • 2021-09-29
    相关资源
    最近更新 更多