抓住这是一个不好的做法吗 Throwable?

例如这样的事情:

try {
    // Some code
} catch(Throwable e) {
    // handle the exception
}

这是一种不好的做法还是我们应该尽可能具体?

有帮助吗?

解决方案

您需要尽可能具体。否则无法预料的错误可能会以这种方式蠕动。

除了, Throwable 覆盖 Error 也是通常没有返回点。您不想捕获/处理,您希望您的程序立即死亡,以便您可以正确修复它。

其他提示

这是一个坏主意。事实上,甚至捕获的世代植物都是一个坏主意。让我们考虑一个例子:

try {
    inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(Throwable e) {
    inputNumber = 10; //Default, user did not enter valid number
}
. 现在,让我们说getUserInput()块有一段时间,另一个线程以最糟糕的方式停止您的线程(它调用thread.stop())。您的Catch块将捕获Exception错误。这是超级糟糕的。捕获异常后的代码的行为在很大程度上是未定义的。

捕捉异常发生类似的问题。可能是生成的因子因InterruptException而失败,或者在尝试记录结果的同时拒绝异常,或者所有各种各样的失败。你不知道出了什么问题,因为它,你也不知道如何解决问题。

你有三个更好的选择:

1 - 捕获您知道如何处理的例外:

try {
    inputNumber = NumberFormat.getInstance().formatNumber( getUserInput() );
} catch(ParseException e) {
    inputNumber = 10; //Default, user did not enter valid number
}
.

2 - 重新开始您遇到的任何异常,不知道如何处理:

try {
    doSomethingMysterious();
} catch(Exception e) {
    log.error("Oh man, something bad and mysterious happened",e);
    throw e;
}
.

3 - 使用最终块,以便您不必记得Rethrow:

 Resources r = null;
 try {
      r = allocateSomeResources();
      doSomething(r);
 } finally {
     if(r!=null) cleanUpResources(r);
 }
.

另请注意,当您抓住 Throwable, ,你还可以抓住 InterruptedException 这需要特殊的处理。看 处理InterruptedException 更多细节。

如果您只想捕获未经检查的异常,您也可以考虑这种模式

try {
   ...
} catch (RuntimeException exception) {
  //do something
} catch (Error error) {
  //do something
}

这样,当您修改代码并添加可以引发已检查异常的方法调用时,编译器会提醒您,然后您可以决定针对这种情况做什么。

直接从错误类的javadoc(这建议不要捕获这些):

 * An <code>Error</code> is a subclass of <code>Throwable</code> 
 * that indicates serious problems that a reasonable application 
 * should not try to catch. Most such errors are abnormal conditions. 
 * The <code>ThreadDeath</code> error, though a "normal" condition,
 * is also a subclass of <code>Error</code> because most applications
 * should not try to catch it. 

 * A method is not required to declare in its <code>throws</code> 
 * clause any subclasses of <code>Error</code> that might be thrown 
 * during the execution of the method but not caught, since these 
 * errors are abnormal conditions that should never occur. 
 *
 * @author  Frank Yellin
 * @version %I%, %G%
 * @see     java.lang.ThreadDeath
 * @since   JDK1.0
.

如果您绝对不能从方法中没有异常泡沫,这不是一个不好的练习。

如果您真的无法处理异常,这是一个糟糕的练习。更好地添加“投掷”到方法签名,而不是捕获和重新投掷或更糟糕,将其包裹在runtimeexception并重新投掷。

捕获量会有有时需要如果您使用过热情地抛出错误,否则您的图书馆可能会杀死您的应用程序。

但是,在这些情况下,最好只指定库抛出的特定错误,而不是所有thllables。

throwable是所有类的基类,而不是可以抛出(不仅例外)。如果你抓住了一个OutofMemoryError或KernelEror,你可以做些什么(参见捕获java。lang.error?

捕捉异常应该足够。

取决于您的逻辑或更具体地对您的选项/可能性。如果有任何特定的例外,您可以以有意义的方式反应,您可以先捕获它并执行此操作。

如果没有,你确定你会为所有例外和错误做同样的事情(例如用错误消息退出),而不是捕获throwable的问题。

通常是第一个案例持有,你不会抓住扔石头。但仍有很多案例,其中捕获它的工作正常。

尽管这被描述为一种非常糟糕的做法,但有时您可能会发现 稀有的 情况下它不仅有用而且是强制性的。这里有两个例子。

在 Web 应用程序中,您必须向用户显示有意义的完整错误页面。这段代码确保发生这种情况,因为它很大 try/catch 围绕所有请求处理程序(servlet、struts 操作或任何控制器......)

try{
     //run the code which handles user request.
   }catch(Throwable ex){
   LOG.error("Exception was thrown: {}", ex);
     //redirect request to a error page. 
 }

}

再举一个例子,假设您有一个服务于资金转账业务的服务类。该方法返回一个 TransferReceipt 如果转移完成或 NULL 如果不能的话。

String FoundtransferService.doTransfer( fundtransferVO);

现在成像你得到一个 List 用户的资金转账,您必须使用上述服务来完成所有这些操作。

for(FundTransferVO fundTransferVO : fundTransferVOList){
   FoundtransferService.doTransfer( foundtransferVO);
}

但如果会发生什么 任何 异常发生?您不应该停止,因为一笔转账可能成功,也可能不成功,您应该继续遍历所有用户 List, ,并将结果显示给每次传输。所以你最终得到了这段代码。

for(FundTransferVO fundTransferVO : fundTransferVOList){
    FoundtransferService.doTransfer( foundtransferVO);
 }catch(Throwable ex){
    LOG.error("The transfer for {} failed due the error {}", foundtransferVO, ex);
  }
}

你可以浏览很多开源项目来看看 throwable 确实被缓存和处理。例如,这里是搜索 tomcat,struts2primefaces:

https://github.com/apache/tomcat/search?utf8=%E2%9C%93&q=catch%28Throwable https://github.com/apache/struts/search?utf8=%E2%9C%93&q=catch%28Throwable https://github.com/primefaces/primefaces/search?utf8=%E2%9C%93&q=catch%28Throwable

问题有点模糊;你是在问“可以抓住吗 Throwable”,或者“可以抓到吗? Throwable 并且什么也不做”?这里很多人都回答了后者,但这是一个次要问题;99% 的情况下,无论您是否正在捕获异常,您都不应该“消耗”或丢弃该异常 Throwable 或者 IOException 管他呢。

如果您传播异常,答案(就像许多问题的答案一样)是“视情况而定”。这取决于你对异常做了什么——为什么你要捕获它。

一个很好的例子来说明为什么你想要抓住 Throwable 是在出现任何错误时提供某种清理。例如在 JDBC 中,如果事务期间发生错误,您可能希望回滚事务:

try {
  …
} catch(final Throwable throwable) {
  connection.rollback();
  throw throwable;
}

请注意,异常并未被丢弃,而是被传播。

但作为一般政策, Throwable 因为您没有理由并且懒得查看抛出了哪些特定异常,这是糟糕的形式和坏主意。

一般来说,您想要避免捕获生成的捕获量,但我可以想到(至少)两个特定的情况,在那里适合这样做:

  • 要响应错误,尤其是无害的错误,尤其是无害的。
  • 您是否在实现类似于 executorservice.submit(),要求您将例外转发回用户,以便它们可以处理它。

如果我们使用 throwable ,那么它也会涵盖错误

示例。

    public class ExceptionTest {
/**
 * @param args
 */
public static void m1() {
    int i = 10;
    int j = 0;
    try {
        int k = i / j;
        System.out.println(k);
    } catch (Throwable th) {
        th.printStackTrace();
    }
}

public static void main(String[] args) {
    m1();
}
.

}

输出:

java.lang.ArithmeticException: / by zero
at com.infy.test.ExceptionTest.m1(ExceptionTest.java:12)
at com.infy.test.ExceptionTest.main(ExceptionTest.java:25)
.

throwable是所有错误和卓越的超类。 如果在Catch子句中使用ROLLABLE,它不仅会捕获所有异常,它也会捕获所有错误。JVM抛出错误以指示不打算通过应用程序处理的严重问题。典型的例子是outofmemoryerror或stackoverfloweror。两者都是由申请控制之外的情况引起的,无法处理。所以你不应该抓住thlowables,除非你的相当自信,它只是一个例外居住在洛克里面。

虽然捕获 Throwable 通常是不好的做法(正如该问题的众多答案所阐明的那样),但捕获 Throwable 的场景 Throwable 有用的很常见。让我用一个简化的例子来解释我在工作中使用的一个这样的案例。

考虑一种执行两个数字相加的方法,并在成功相加后向某些人发送电子邮件警报。假设返回的数字很重要并且由调用方法使用。

public Integer addNumbers(Integer a, Integer b) {
    Integer c = a + b;          //This will throw a NullPointerException if either 
                                //a or b are set to a null value by the
                                //calling method
    successfulAdditionAlert(c);
    return c;
}

private void successfulAdditionAlert(Integer c) {
    try {
        //Code here to read configurations and send email alerts.
    } catch (Throwable e) {
        //Code to log any exception that occurs during email dispatch
    }
}

发送电子邮件警报的代码会读取大量系统配置,因此该代码块可能会引发各种异常。但是我们不希望在警报调度期间遇到的任何异常传播到调用者方法,因为该方法只关心它提供的两个 Integer 值的总和。因此,发送电子邮件警报的代码被放置在 try-catch 块,其中 Throwable 被捕获并且仅记录任何异常,从而允许流程的其余部分继续。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top